在外部 API 接口中添加新成员和扩展方法

Adding new members and extending methods in an external API interface

我正在使用 SOLIDWORKS API 在 Visual Studio 中构建一个 VB.NET 应用程序 - 我的应用程序通过 COM 连接到 SOLIDWORKS 应用程序,并在其中使用各种 API 来电。 API 通过将项目引用添加到 SOLIDWORKS .dll 文件来访问。出于法律原因,这些文件必须嵌入到我的应用程序的可执行文件中。

这个问题并不特定于那个API,但我会尽力解释我想做什么。有一个名为 Body2 that governs manipulation of model objects (bodies) in 3D space. For example, Body2 interface provides a method ApplyTransform that allows moving or rotating a certain body by applying a MathTransform(变换矩阵)的 SOLIDWORKS API 界面:

ModelBody.ApplyTransform(rotationMatrix) 'rotates the body

现在,Body2 object 不存储这些变换矩阵 - 它们被应用并被遗忘。但是,在我的应用程序中,我需要持久地存储该信息,以便在某个时候,我可以反转所有转换,并且 return body 到它的原始位置。

因此,我想通过向其添加一个新的 属性 来扩展 Body2 接口,称为“CombinedTransformMatrix”,以便每次调用 ApplyTransform 时,我也可以更新值这个属性,例如:

ModelBody.ApplyTransform(rotationMatrix)
ModelBody.CombinedTransformMatrix.Multiply(rotationMatrix)
ModelBody.ApplyTransform(translationMatrix)
ModelBody.CombinedTransformMatrix.Multiply(translationMatrix)

当我最终想要 return body 到它原来的位置时,我可以调用:

ModelBody.ApplyTransform(ModelBody.CombinedTransformMatrix.Inverse)
ModelBody.CombinedTransformMatrix = New MathTransform 'reset matrix

理想情况下,扩展 ApplyTransform 方法会非常好,这样它会自动更新 CombinedTransformMatrix,例如:

Overrides Function ApplyTransform(Xform As MathTransform) As Boolean
   'Do whatever SOLIDWORKS does in this function

   'My additional code:
   Me.CombinedTransformMatrix.Multiply(Xform)
End function

(我知道我应该做一个扩展而不是覆盖,但我不知道怎么做)

如果可能的话,我可以简化 body 转换的代码,因为 CombinedTransformMatrix 会自动更新:

'Rotate and move
ModelBody.ApplyTransform(rotationMatrix)
ModelBody.ApplyTransform(translationMatrix)

'Return to original position
ModelBody.ApplyTransform(ModelBody.CombinedTransformMatrix.Inverse)
ModelBody.CombinedTransformMatrix = New MathTransform 'reset matrix

我非常喜欢这种解决方案,而不是从 Body2 创建一些派生的 class,或者制作某种包装器 class 来存储 CombinedTransformMatrixBody2object。我想将该位存储在 object 本身中。至于派生 class,Visual Studio 甚至不允许我从 Body2 继承 - 说“'Body2Class' 在其程序集配置为嵌入互操作类型时是不允许的。” .而且我必须嵌入这些 .dll 文件,否则我将不得不将它们与我的应用程序的 .exe 一起发送,这是 SOLIDWORKS 法律禁止的。

我想要的有可能吗?我可以在不创建派生的 class 的情况下将 CombinedTransformMatrix 添加到 Body2 接口吗?是否可以在不知道该方法是如何实现的情况下使用我的附加代码扩展该 ApplyTransform 方法?

如果不是,实现我想要的下一个最佳解决方案是什么?就像我说的,我非常想避免 Body2 之外的包装器或其他变量,因为会有很多这样的 Body2 objects,它们将在应用程序的整个生命周期中持续存在,每个都有不同的转换,因此必须将它们的转换信息存储在它们自身之外会使我的代码严重复杂化。

没有通用的方法可以做到这一点。您可以维护单独的字典,将 COM object(例如本例中的 IBody2)作为键,将附加参数(标签)作为值。当指针被销​​毁时,您将需要手动更新字典以删除数据。然而,有一些特定的 SW 接口确实有一些方法来关联自定义数据(类似于标签)。例如,IBody2 有 IBody2::AddPropertyExtension2 允许将自定义数据与 body 本身相关联,IEntity 有 IEntity::CreateStringAttributeDefinition(注意,这不是记录的方法)等

但是对于 Windows 控件没有通用的 System::Windows::Forms::Tag 属性 或对于 COM 类.[=10 存在 DependencyObjects 的依赖性 属性 =]