I’m on day 2 of going through assemblies in .NET 4.0. I may miss a day here and there, but I want to find out what is in all the libraries. For some of the bigger libraries, I think I’ll do a namespace breakdown over several days.
The assembly today is CustomMarshalers, and it has very few classes; 4 to be exact.
CustomMarshalers, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
FullTrust: True
In GAC: True
Number of types: 4
Number of namespaces: 1
Types:
Class System.Runtime.InteropServices.CustomMarshalers.ExpandoToDispatchExMarshaler
Class System.Runtime.InteropServices.CustomMarshalers.EnumeratorToEnumVariantMarshaler
Class System.Runtime.InteropServices.CustomMarshalers.TypeToTypeInfoMarshaler
Class System.Runtime.InteropServices.CustomMarshalers.EnumerableToDispatchMarshaler
These classes all handle special scenarios for interacting with COM. Since there are only 4 classes, I’ll cover each.
ExpandoToDispatchExMarshaler
The CLR will not use this marshaler automatically. You need to know when it is needed. When P/Invoking a function or declaring a CLR wrapper for a COM object, you may have an object that only implements IDispatchEx. IDispatch was originally created for Visual Basic and allows late bound dispatch to properties. In other words, it allows for duck typing. IDispatchEx allows for an object to add and remove methods to a given object and exists to support dynamic features of Windows Script Host (languages: VBScript and JScript).In the .NET world, one adds and removes members from a type by implementing the System.Runtime.InteropServices.IExpando interface. From reading the documentation, it appears that if your underlying COM object implements IDispatchEx, you should must the infrastructure to marshal to an IExpando.
void UseCustomMarshaler([MarshalAs(UnmanagedType.CustomMarshaler,
MarshalTypeRef=typeof(ExpandoToDispatchExMarhsaler))] IExpando expando);
EnumeratorToEnumVariantMarshaler
COM allows code to enumerate a collection of VARIANT data using the IEnumVARIANT interface. A VARIANT allows one to put an integer, boolean, string, or complex object inside of a uniform binary type. In .NET, one would have a bunch of COM values that one wants to treat as System.Object. The CLR knows to use this marshaler when marshalling between a COM IEnumVARIANT and a .NET IEnumerator.
TypeToTypeInfoMarshaler
COM contains an interface named ITypeInfo. ITypeInfo is used for reading information about objects. Type browsers use ITypeInfo to figure out the characteristics and methods of objects contained in COM type libraries. A type library will be in a .tlb file or embedded in the dll/exe. Compilers use ITypeInfo to compile references to members of a type. If you export a .NET type to COM, the tools that read ITypeInfo need a way to read the information about your .NET types as ITypeInfo. Fortunately, this public type is meant to be used by the framework and not by your code. Still, it’s good to know what the class does.
EnumerableToDispatchMarshaler
This type is automatically used when bridging between an System.Collections.IEnumerable and an IDispatch where a member with a DISPID of -4 (enumerable member) is present. You will typically interact with this class when using tlbimp.exe to consume a type library from within your .NET application.
Summary
Whew-that was a lot of detail to cover. I can’t promise to do this every day, but I know that COM interop is one of my weak points. As you find issues with these descriptions, let me know. These blog entries are simply documenting my trip through the class libraries and all the reading I’m doing.