我通过我从COM DLL生成的互操作程序集调用来自C#项目的COM组件。 COM接口定义了DispIds,我已经验证它们出现在生成的互操作程序集中。
根据经验,如果我将COM组件升级到更新版本,则互操作调用会出现严重错误(就像它调用错误的COM方法一样)。
这是预期的,即interop程序集是否紧密绑定到为其生成的COM接口的特定版本?我天真地认为,只要DispIds和函数原型在新的COM组件中匹配,它们就可以正常运行。
有没有办法告诉CLR在通过互操作程序集调用COM组件时使用DispIds,即后期绑定类型? (我知道使用反射式C#代码可以使用后期绑定,但这不如互操作程序集方便。)
答案 0 :(得分:2)
我找到了Brian Long的文章.NET Interoperability: COM Interop:
最常见的要求是使用早期绑定来获得编译时类型检查并直接(好吧,直接得到)对COM对象的vtable调用。上面的[interop assembly]示例采用了这种方法。
互操作程序集导致"直接vtable调用"听起来它不适用于新版本的界面(除非,新的方法可能只添加到界面的末尾,即到vtable的末尾?)。
也许某人可以证实或提供更完整的答案?
答案 1 :(得分:2)
DispIds仅在客户端程序员使用后期绑定时使用。如果那是你想要他做的,那么你必须强制执行它。这很容易,在接口上应用[InterfaceType(ComInterfaceType.InterfaceIsDispatch)]属性。如果你没有编写一个接口而只编写一个类,那就给它[ClassInterface(ClassInterfceType.AutoDispatch)]属性。
客户端程序员尝试使用危险的早期绑定现在会失败,他必须编写后期绑定代码。不要指望感谢信。
唯一的另一种方法是删除您现在使用的[Guid]属性。这是非常危险的,让CLR自动生成guid,这样当你更改界面时它会自动变化。客户端程序员得到一个体面的E_NOINTERFACE错误,而不是调用完全错误的方法。好吧,不要指望一个感谢信:))