嵌入互操作类型下SOLIDWORKS API接口新增属性与扩展方法咨询
结论先行
你的核心需求无法直接实现,原因如下:
- 你无法直接为
Body2接口新增带状态的属性:Body2是SolidWorks提供的COM互操作接口,接口定义本身是不可修改的,你无法向COM对象的原生内存中写入额外的自定义数据。同时VB.NET不支持扩展属性,即便用支持扩展属性的高版本C#,扩展属性的状态也只能存在于.NET侧,无法存入COM对象内部。 - 你无法直接扩展原生
ApplyTransform方法的逻辑:你没有办法拦截COM对象的原生方法调用,除非你主动调用自己封装的逻辑,否则原生方法执行时不会触发你自定义的更新代码。 - 嵌入互操作类型的配置本身就禁止继承COM包装类,你看到的报错是设计使然,没有绕过的可能。
最优替代方案:使用ConditionalWeakTable+扩展方法模拟效果
这个方案完全不需要创建派生类或包装类,不需要手动管理变换矩阵的生命周期,代码使用体验和你理想中的写法几乎一致,且完全兼容嵌入互操作类型的要求。ConditionalWeakTable是.NET内置的弱引用字典,它会自动跟踪Body2对象的生命周期,当Body2对象被GC回收时,对应的变换矩阵会自动被清理,不会造成内存泄漏,也不需要你手动维护映射关系。
实现代码
Imports System.Runtime.CompilerServices Imports SolidWorks.Interop.sldworks Imports SolidWorks.Interop.swconst Public Module Body2TransformExtensions ' 内部存储Body2和对应累计变换矩阵的弱引用映射 Private ReadOnly _combinedTransforms As New ConditionalWeakTable(Of Body2, MathTransform)() ''' <summary> ''' 获取Body2的累计变换矩阵,默认返回单位矩阵 ''' </summary> <Extension()> Public Function GetCombinedTransformMatrix(ByVal body As Body2) As MathTransform Dim transform As MathTransform = Nothing If Not _combinedTransforms.TryGetValue(body, transform) Then transform = New MathTransform() ' 初始为单位矩阵 _combinedTransforms.Add(body, transform) End If Return transform End Function ''' <summary> ''' 设置Body2的累计变换矩阵 ''' </summary> <Extension()> Public Sub SetCombinedTransformMatrix(ByVal body As Body2, ByVal value As MathTransform) If _combinedTransforms.TryGetValue(body, Nothing) Then _combinedTransforms.Remove(body) End If _combinedTransforms.Add(body, value) End Sub ''' <summary> ''' 带变换追踪的ApplyTransform,自动更新累计变换矩阵 ''' </summary> <Extension()> Public Function ApplyTransformWithTracking(ByVal body As Body2, ByVal xform As MathTransform) As Boolean ' 调用原生ApplyTransform逻辑 Dim result As Boolean = body.ApplyTransform(xform) ' 自动更新累计矩阵 Dim current = body.GetCombinedTransformMatrix() current.Multiply(xform) body.SetCombinedTransformMatrix(current) Return result End Function ''' <summary> ''' 重置Body2到初始位置并清空累计变换矩阵 ''' </summary> <Extension()> Public Sub ResetToOriginalTransform(ByVal body As Body2) Dim combined = body.GetCombinedTransformMatrix() body.ApplyTransform(combined.Inverse) body.SetCombinedTransformMatrix(New MathTransform()) End Sub End Module
使用示例
' 旋转与移动,和你理想中的写法几乎无差别 ModelBody.ApplyTransformWithTracking(rotationMatrix) ModelBody.ApplyTransformWithTracking(translationMatrix) ' 一键恢复到初始位置 ModelBody.ResetToOriginalTransform()
方案优势
- 完全兼容嵌入互操作类型的要求,不需要额外分发SolidWorks的dll,符合合规要求
- 不需要修改原生
Body2的任何逻辑,不需要派生或包装类,业务代码中仍然使用原生Body2对象 - 自动管理生命周期,无内存泄漏风险,即便存在大量
Body2对象也不会额外增加代码维护复杂度 - 唯一限制是你自己的代码需要统一调用
ApplyTransformWithTracking替代原生的ApplyTransform,避免矩阵不同步
内容的提问来源于stack exchange,提问作者Justin8051
相关产品推荐
相关产品推荐

