Help with C# calling changing COM interface?

Wednesday 1 September 2004

We’ve got an aggravating problem with a C# project, and I’m hoping someone out there can point me in the right direction.

Working in Dev Studio .NET, we have two projects: a C++ executable that implements a COM interface, and a C# executable that calls that interface. The C# project has a reference to the C++ executable. The COM interface is under development, so it is constantly changing: new methods being added, the interface definitions changing, and so on. We’re seeing a number of bad results.

On some developers machines, the projects build fine, but then execution fails: COM calls from C# to C++ are going to the wrong entry points (a call to method A ends up calling method B instead). On the build machine, the code won’t compile. A change in the number of parameters to a method results in a compile error, as if the interface definition hadn’t changed.

We’ve tried all sorts of combinations of gacutil and COM registration, and haven’t found the secret handshake that just makes it work.

Does anyone know the elusive answer?

Comments

[gravatar]
Omer Trajman 9:38 AM on 1 Sep 2004

If I recall correctly, in order to avoid the painfully slow process of generating .Net headers for COM objects, MS will globally cache the wrapper (some global code cache in the windows dir I believe). There are also per user and per project caches. In theory, MS obeyed the cardinal rule of COM and will force recreate the wrapper if you increase the interface version number (a good practice when changing an interface that other people are using). Otherwise you have to hunt down the wrapper and delete it, then recreate it.

[gravatar]
Steven Campbell 11:43 AM on 1 Sep 2004

The combination that works for us is to regenerate primary interops (with a new version number) every time that the COM interface changes. We then (on the developers machines):
1) register the COM DLL
2) copy new primary interops
3) using regasm with the /codebase option to register the interops.

We do not bother installing the interops in the GAC, since they change too often. The most important step is the registering of the interops, because this lets Visual Studio know where to find them.

[gravatar]
Roger Lipscombe 3:38 AM on 4 Sep 2004

I saw something similar yesterday. I'm not sure how you're generating the wrappers -- our solution has both the C# and C++ (ATL) projects in it -- and we used the Add Reference/COM dialog to add the output of the C++ project to the C# project.


We ran into two problems:
1. If you've got ActiveX controls, you can't rebuild the C++ project, because it's still open in the designer. The solution: close all windows and restart VS.


2. If you change the interface (this seems to be what you're seeing), the new members won't appear. You need to restart VS, which causes it to rebuild the wrappers when the solution is reloaded. There doesn't seem to be a forced rebuild option anywhere.


However, we've not got as far as being clever enough to register the interops in the GAC, or anything like that, so you might be well past the problems we're seeing.


I was playing with using tlbimp and aximp as custom build steps, but I 've not got very far with that yet.

Add a comment:

Ignore this:
Leave this empty:
Name is required. Either email or web are required. Email won't be displayed and I won't spam you. Your web site won't be indexed by search engines.
Don't put anything here:
Leave this empty:
URLs auto-link and some tags are allowed: <a><b><i><p><br><pre>.