Christopher Eck's Old Unused Blog

I've left the CLR team.

How do COM objects interact with the CLR type system? (cont.)

Today, I'll continue my discussion on how COM objects interact with the CLR type system by talking about consuming COM objects from managed code in a late bound fashion.  Sorry there is no example code included in this one, but I'm in a hurry :)

As defined in my last post, late binding refers to access and use of a type that is not known at compile time.  Note that there is a difference in compile-time late binding and late-bound method invocation.  The former refers to knowledge of the type at compile time while the latter refers to how methods are invoked on an object at runtime.  I'll cover both of these below.


How do I get an instance at runtime that represents a COM object?

First, I'll mention that if the metadata for a COM object is not available, the CLR will substitute the type with System.__ComObject, a generic type that provides no methods and acts as a representative for a non-strongly typed COM object.


1) You could use PInvoke to call into the IClassFactory for the object.

2) You could use Type.GetTypeFromCLSID to get a managed type object which represents the COM object's type.  You could then activate an instance of this type with Activator.CreateInstance.

3) You could use Marshal.GetTypeForITypeInfo to get a managed type object which represents the COM object's type.  This API is interesting in that it will automatically import the matching type library (if available) and create an IA on the fly.  You will not get the generic System.__ComObject out of this API if the type library is available.  Just as above, you can activate an instance of this type with Activator.CreateInstance.

4) You could receive an instance of a COM object as a return or out/ref parameter of another call to or from native code.


Now you have a runtime generated type.  Depending on which API and method you used you will either have a strongly typed object or the generic System.__ComObject.


To call methods on this object, you'll end up having to cast the object to a real type, or use Type.InvokeMember since the compiler didn't know what type you were using when it emitted IL.  For COM objects, Type.InvokeMember will marshal the arguments to their native versions, get the object's IDispatch interface, and call IDispatch::Invoke.  This is the same path taken for strongly typed COM objects that only allow late-bound method invocation (in other words, for COM objects that don't supply a vtable and only allow calls via IDispatch).

VB actually calles Type.InvokeMember under the covers for you for late-bound types.


Any call that goes through IDispatch::Invoke indicates late-bound invocation on a COM object.
Any call that goes through Type.InvokeMember indicates late-bound invocation on a managed object (which could be a RCW placeholder object in which case we'll end up going through IDispatch::Invoke).

 

Next time, I'll be covering calls from COM into the CLR...

Published Thursday, November 11, 2004 10:45 AM by chriseck

Comments

 

Doug McClean said:

Careful when saying that System.__ComObject is a "generic type," since that has a formal meaning now :).
November 11, 2004 11:38 AM
 

Stephane Rodriguez said:


Hosting the CLR in a native app, and having an equivalent of "ThisDocument" à la VBA be executed in managed code (pointing to a native COM SDK) sounds like a no-brainer. But would it work? It looks like we need to resolve the type and "point" to the current instance of the COM object hosted by the app as well.
November 11, 2004 1:59 PM
 

Christopher Eck s Old Unused Blog How do COM objects interact with | Hair Growth Products said:

June 9, 2009 4:23 AM
Anonymous comments are disabled

This Blog

Syndication

Tags

No tags have been created or used yet.

News

Disclaimer

All postings provided "AS IS" with no warranties, and confer no rights.

© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker