You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

跨项目使用SolidWorks API扩展方法触发EntryPointNotFoundException求助

我来帮你拆解这个问题——这个EntryPointNotFoundException其实是SolidWorks COM互操作中常见的类型隔离问题,咱们一步步分析原因,再给出可行的复用方案:

异常原因分析

这个报错的核心矛盾在于SolidWorks COM互操作类型的加载/嵌入配置不一致,以及RCW(Runtime Callable Wrapper)的类型隔离特性:

  1. Embed Interop Types 配置差异
    当你在项目B中引用SolidWorks互操作程序集时,如果开启了Embed Interop Types(NuGet的SolidWorks API包默认会开启这个选项),编译器会把Component2这类互操作类型的定义直接嵌入到项目B的输出程序集里。而如果项目A的这个配置和项目B不一样(比如关闭,或者虽然开启但编译上下文导致嵌入类型不兼容),那么项目A里的Component2类型和项目B里嵌入的Component2类型,会被CLR当成完全不同的类型。

    当你在项目A里拿到扩展方法返回的字典后,用OrderBy(kv => kv.Key)访问Component2.Name2时,CLR会试图在项目A的Component2类型上找Name2的入口点,但字典里的对象其实是项目B嵌入类型的RCW包装,类型不匹配就直接抛出了EntryPointNotFoundException

  2. 程序集加载上下文隔离
    SolidWorks的COM对象都是通过RCW包装的,不同程序集加载上下文中的RCW类型哪怕名字一样,也会被视为不同类型。如果项目B的程序集加载上下文和项目A(插件主程序集)不一致,同样会导致类型识别失败。

解决方案:实现项目B中复用扩展方法

要在项目B里安全复用这个扩展方法,关键是保证互操作类型的一致性,具体可以这么做:

1. 统一两个项目的互操作类型配置

  • 打开项目A和项目B的引用属性,找到SolidWorks的互操作程序集(比如SolidWorks.Interop.sldworks.dll)。
  • 确保两个项目的Embed Interop Types属性完全一致
    • 推荐设置为True(NuGet包默认值),这样编译器会嵌入必要的互操作类型,避免版本依赖问题,但必须两个项目同时开或关。
    • 如果设为False,一定要保证两个项目引用的是完全相同版本的互操作程序集,并且程序集能被正确加载。

2. 调整扩展方法返回类型(可选,兼容不同上下文)

如果没法保证配置完全一致,可以修改扩展方法的返回类型,绕过强类型的RCW差异:

public static class Extensions 
{ 
    public static IDictionary<string, dynamic> GetAllComponentsByName(this AssemblyDoc assyDoc) 
    {
        return ((object[])assyDoc.GetComponents(false))
            .Cast<dynamic>()
            .ToDictionary(c => c.Name2, c => c); 
    }
}

这样项目A中访问kv.Key时会通过动态绑定直接调用COM对象的属性,避开RCW类型不匹配的问题。不过这种方式会失去编译时类型检查,需要根据你的场景权衡使用。

3. 确保项目B的程序集被正确加载

作为SolidWorks插件的类库,项目B的输出程序集要和项目A的插件程序集在同一目录,或者能被SolidWorks的加载机制找到。可以在项目B的属性里设置Copy Local = True,让它的输出程序集自动复制到项目A的输出目录中。

4. 验证互操作程序集的一致性

确认项目A和项目B引用的SolidWorks互操作程序集来源完全相同:

  • 都是通过同一个NuGet包安装的,版本完全一致。
  • 别混合用手动添加的互操作程序集和NuGet包,这会导致类型定义和版本不一致。

内容的提问来源于stack exchange,提问作者Kjara

火山引擎 最新活动