Recently I wrote a managed wrapper for BITS to use in blinkBox's download manager application, which necessitates COM interop. This was made a little tricky due to the fact that BITS doesn't ship with primary interop assemblies or a type library; simply with an IDL interface definition file. However, using some command line tools it's quick to translate the IDL file into C# interop types which you can use. Note that although I'm demonstrating the process using BITS, this works with pretty much any IDL file.
First we need to convert the IDL file into a type library using MIDL:
midl "C:\Program Files\Microsoft SDKs\Windows\v6.0\Include\bits.idl"
This generates a type library named bits.tlb which can be used with the .NET type library importer:
tlbimp bits.tlb /out:Interop.Bits.dll
Now we have an interop DLL named Interop.Bits.dll. We could use this directly (in which case we'd have wanted to use the /keyfile option of tlbimp to strong name the assembly) however as is common when importing type libraries, some of the interop signatures generated aren't quite right. In the case of the BITS library the two main issues are that all arrays in method signatures are imported as single objects, and the enumeration interface 'move next' methods have the default COM HRESULT mapping applied whereas I'd prefer to mark them with PreserveSig and check the HRESULT manually so that reaching the end of the enumerator doesn't raise an exception.
Another reason you might not want to use the interop DLL directly is that it's an additional assembly to manage, version, and deploy. If you know the only place the interop definitions will be used is in a library that wraps them in more user-friendly .NET types then you make the library easier to use and maintain by moving them inside it.
To convert the interop DLL into managed code use Lutz Roeder's Reflector, which can translate MSIL into a number of .NET languages including C# and Visual Basic. It's an invaluable tool for inspecting assemblies you don't have the source code for, though if you try to inspect Reflector with itself you'll see it's obfuscated which I find rather ironic. To save yourself the effort of cutting and pasting the disassembled code into files, just dump them out with Denis Bauer's FileDisassembler add-in.
MIDL often generates a bunch of unused structures with funny names like __foo_bar_0001 so you can safely delete pretty much any source file whose name starts with a double underscore, then you're free to refactor the rest to remove any leading underscores from names, and modify the signatures of the methods so they match where necessary.
Posted
Mar 24 2008, 01:53 PM
by
Greg Beech