开发者

What is the advantage of defining an interface for .NET classes exposed to COM?

I am building a library which needs to be referenced from VBA so I need to provide a type library to support early binding. Most of the examples I have seen define a interface for classes which are exposed to COM e.g.

[Guid("D6F88E95-8A27-4ae6-B6DE-0542A0FC7039")]     
[InterfaceType(ComInterfaceType.InterfaceIsDual)]     
public interface IMyClass 

[Guid("13FE32AD-4BF8-495f-AB4D-6C61BD463EA4")]     
[ClassInterface(ClassInterfaceType.None)]     
[ProgId("M开发者_C百科yNamespace.MyClass")]     
public class MyClass : IMyClass

Is there any disadvantage in having a class implement the interface directly using ClassInterface.AutoDual? For more complex classes I like having interfaces to clearly define which members are exposed com without having to use the ComVisible attribute everywhere. But I will also have a number of fairly trivial data classes like event args which will be exposed to COM in their entirety. I have also seen examples which explicitly set dispids on interfaces - is there any advantage in doing this?


Yes, there's a big one: DLL Hell is nasty with early binding. The COM client directly calls the method through the v-table pointer. If an outdated COM server that uses the same interface IIDs (which in itself is a crime) is resident then this may call a wrong or non-existing method. The runtime failure, usually an AccessViolation, is very hard to diagnose.

This doesn't happen with late binding, there will (usually) be a reasonable diagnostic, like DISP_E_MEMBERNOTFOUND or DISP_E_BADPARAMCOUNT. Which is why Microsoft heavily favors ComInterfaceType.InterfaceIsIDispatch. The disadvantage is that late binding is quite slow. Another one is that errors are only caught at runtime, not compile time.

Setting the DispIDs is very rarely useful. Some legacy Microsoft products used dispid binding, pre-compiling the dispid into the code. It is roughly twice as fast as late binding because there's no need for the IDispatch::GetIDsOfNames() call. It is very unlikely you'll still encounter them in the wild, certainly not any VBA version.

A decent KB article on the topic is here.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜