Difference between Dual interface and Dispatch onl

2019-04-10 08:03发布

问题:

I am implementing a c# COM client against a C++ COM server. The COM client functions correctly when I mark the COM interface as "Dual" but it throws an InvalidCastException when I remove the "Dual" attribute.

Therefore the easy fix for me is to mark it as Dual. But from reading online, it looks like it is not the recommended approach to use for COM servers. Can anyone explain to me the significance (in layman terms) to marking an interface as dual and why it would not be recommended?

I only need it for testing purposes, and I'm using C# client (don't anticipate that I ever will use VB)

Alternatively, can anyone point me to a good walkthrough on creating a C# COM client for non-Dual interfaces (the examples on MSDN all are dual interfaces) Thanks!

回答1:

When you create a COM object for public consumption, you have different options as to how you can make your interface(s) available for public consumption.

If you only want to make your COM object available to low-level programming languages (like C++, C, C#, etc.) which support things like pointers and vtables, you can just create a "custom" interface which inherits from IUnknown.

The problem with this approach is that your COM object will not be available to scripting clients (VBScript, JScript, WScript, etc.), as these clients don't understand pointers and vtables. Instead, you would implement your COM object interface as a derivation of IDispatch. IDispatch provides some methods that allow a scripting client to dynamically discover its methods and properties at runtime instead of compile time. However, this process is less efficient than using IUnknown, as the client has to make extra method calls before calling the desired COM object's method.

So, if you're only targeting low-level programming languages, you could implement your COM interfaces using "custom" interfaces that inherit from IUnknown

If you're only targeting scripting clients, you could implement your interfaces using only IDispatch.

If you want your COM object to be available to scripting languages, and you also want low-level languages to be able to call your methods in a very efficient manner, you should implement both, and this is called "Dual". Probably, Microsoft's examples are all "Dual" because they want their examples to work with both scripting and low-level languages (low-level languages can use IDispatch, but it takes more work).

For more info, I would suggest you watch the .Net Interoperability Course at PluralSight (you can sign up for a free trial subscription). The "COM" part of this course shows you how to create a non-Dual (simple IUnknown interface) as well as "Dual" interfaces.