Runtime Callable Wrappers and their COM objects

by Brian Ensink 25. September 2009 00:15

Today I was testing some fresh code that I had written over the past weeks when I found I needed a fix from another developer.  So I merged changes from the main branch into my local working copy and kicked off a deep rebuild.  The build churned for a while but failed with some unusual errors, not the ordinary syntax errors.  Aww nuts, the code was building fine before I got latest … but now I’m stuck until I fix this.

Ultimately the biggest problem was a circular dependency that I had introduced (it seems obvious now looking back) but that is not what this post is about.  Along the way I ran into this nice little error that stumped me.

> regasm /verbose /tlb:CAP.SIFCatalogHandler.tlb CAP.SifCatalogHandler.dll

Types registered successfully
RegAsm : error RA0000 : Type library exporter encountered an error while processing 'CAP.SifCatalogHandler.SifCatalogHandler, CAP.SifCatalogHandler'. Error: Referenced type is defined in managed component, which is imported from a type library that could not be loaded (type: 'CAP.ICAPCatalog2'; component: 'C:\WINDOWS\assembly\GAC_MSIL\CAP.CAPDOM\1.0.0.0__414f99c4b6a0bb9a\CAP.CAPDOM.dll').

This error came up while trying to register a .NET assembly containing a COM object written in C#.  Notice that this regasm.exe call also generates a TLB file.  The error claims that it cannot load one of the referenced assemblies called CAP.CAPDOM.dll.  This assembly is a runtime callable wrapper (RCW) for an older COM object written in C++.  I checked and rechecked that CAP.CAPDOM.dll existed.  I manually rebuilt it and checked again but I still kept getting the same error.  I even pulled out fuslogvw.exe which showed that CAP.CAPDOM.dll was loading just fine.

Sigh, for once the tools give a detailed four-line error message that seems to say exactly what the problem is but I’m still to slow witted to figure it out.

A few Google searches on this error and I found a number of posts that seemed to generally confirm some sort of dependency error but nothing gelled.  Besides, I already confirmed that the assembly its complaining about actually exists!

Finally I had an idea.  CAP.CAPDOM is a RCW for a COM object.  The RCW exists, but does the COM object?  No.  Does it need to?  I didn’t know the answer at the time but it does need to exist in this case.  This is when I realized I had a circular dependency.  I backed out my changes and built the actual COM object.

This time regasm.exe worked correctly.  Hooray!

I then unregistered the COM object to see what would happen and again the regasm.exe command gave the same error.  Notice that the error text above actually says “Types registered successfully”.  It seems to just fail while generating the TLB.  Perhaps the RCW’s real COM object is only needed when generating a TLB like this.  Perhaps its only needed when the assembly implements an interface originally declared in the missing COM object.  Apparently the RCW alone is enough to code against and compile the project, but not enough to register it with regasm.exe.  Turns out the beautiful four-line error message is spot on and like usual the problem exists between the keyboard and the chair.

The moral of the story is that an assembly load error for an RCW assembly might actually mean the RCW’s COM object DLL is missing. 

I will remember that.

Now I just need to orchestrate something to get around the circular dependency, restore my changes and I’m back in business.

Tags:

Software Development

Project Euler

by Brian Ensink 22. September 2009 23:36

I stumbled on a fun website the other day: Project Euler. Its a site of progressively difficult math and programming problems.  After you solve a problem you submit your computed answer and the site keeps track of which problems you have solved.  This looks like a great source of programming exercises when starting to learn a new language or dusting off an old one.

Tonight I solved Problem #1.  Yes the problem is easy (that’s why its #1!) but my purpose was to use Java for the first time since last millennium.  Fun stuff.

Tags:

Software Development

Platform Invoke Signatures

by Brian Ensink 14. September 2009 23:15

Just about every .NET developer will eventually need to call some magic Windows function to do something that just isn’t exposed by the .NET framework. Often the hardest part of invoking a platform function from C# or VB.NET is figuring out the signature and structure declarations to pass to the unmanaged API. There are two resources I use to make this process less painful.

First is the public wiki at http://pinvoke.net/. This website contains PInvoke signatures for thousands of Win32 platform functions contributed by the community at large. The quality is across the spectrum but generally good and because its a wiki you can fix mistakes, add new signatures and samples.  I’ve contributed a few minor things myself although I can’t remember exactly what anymore.

The second resource is the open source PInvoke Interop Assistant. This very useful tool lets you copy and paste function and structure declarations directly from Windows header files and automatically generates the PInvoke signatures. It even has a command line version that generates interop signatures for an entire header file in one step.

While neither of these resources is 100% foolproof they have been enough to get me through every time I’ve needed to PInvoke something.

Tags:

Software Development

About the author

I am currently a .NET developer and really enjoy the platform.  .NET seems to be able to take the developer whereever he/she wants to go.  To the desktop, to the web, to a database, etc.  At my day job I write desktop apps but I also like to toy with other tech as I have time.