简体   繁体   中英

Can a COM/.NET interop assembly be used with a newer version of the COM component?

I call into a COM component from a C# project, via an interop assembly that I generate from the COM DLL. The COM interface has DispIds defined and I have verified that these appear in the generated interop assembly.

Empirically, if I upgrade the COM component to a newer version, the interop calls go horribly wrong (as if it's calling the wrong COM methods).

Is this expected, ie that the interop assembly is tightly bound to the specific version of the COM interface that it was generated for? I had naively assumed that as long as the DispIds and function prototypes matched up in the new COM component, which they do, it would all work OK.

Is there a way of telling the CLR to use the DispIds when calling into the COM component via the interop assembly, ie a late binding of sorts? (I know it is possible to use late binding using reflection-style C# code, but this would be less convenient than an interop assembly.)

I found Brian Long's article .NET Interoperability: COM Interop :

The most common requirement will be to use early binding to get compile-time type checking and direct (well, as direct as it gets) vtable calls to the COM objects. The [interop assembly] example above took this approach.

An interop assembly resulting in "direct vtable calls" sounds like it would not work with a new version of the interface (unless, perhaps, new methods were only added to the end of the interface, ie to the end of the vtable?).

Perhaps someone can corroborate or provide a more complete answer?

DispIds are only used when the client programmer uses late binding. If that's what you want him to do then you have to enforce it. That's very easy to do, apply the [InterfaceType(ComInterfaceType.InterfaceIsDispatch)] attribute on the interface. If you didn't write an interface but only a class then give it the [ClassInterface(ClassInterfceType.AutoDispatch)] attribute.

Any attempt by the client programmer to use the dangerous early binding will now fail, he must write late-bound code. Don't expect a thank-you note.

The only other way is to remove the [Guid] attribute you now use. It is very dangerous, let the CLR auto-generate the guid so it will automatically be different when you change the interface. And the client programmer gets a decent E_NOINTERFACE error instead of calling the completely wrong method. Well, don't expect a thank-you note :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM