views:

195

answers:

2

I have a managed assembly containing a few classes, and those classes have overloaded methods. I expose the assembly to COM/IDispatch callers via

[ComVisible(true)]

..and also setting the proper Guid, on the assembly itself. I do not define an explicit interface for the COM interop. It's all done dynamically. I run regasm.exe /codebase on the managed DLL and it registers it for COM interop.

When I run OleView, I can see the ProgId's of the various classes in the assembly. But, browsing into those ProgIds, and expanding IDispatch node, there is no TypeLib information for these classes.

Even so, from a script, I can invoke a method that accepts zero arguments or a method that accepts one argument. If there is also an overload that accepts more than one argument, I cannot invoke that method by name. The error I get, consistently, is

Microsoft VBScript runtime error: Wrong number of arguments or invalid property assignment:  <methodname>

From this I understood that COM/IDispatch clients were not able to properly resolve overloaded methods on an object exposed via COM interop.


Then I added

[ClassInterface(ClassInterfaceType.AutoDual)]

...to each of the classes in question. After regasm.exe on the DLL, I can see typelib information for each method, under the IDispatch node.

What I found is that overloaded methods automatically get a name that includes an appended suffix. MethodX will expose overloads in the auto-generated typelib assembly as MethodX, MethodX_2, MethodX_3, and so on.

And I found that by referencing the method names with those suffixes, I could invoke overloaded methods, although not with the common name.

More interestingly, if I then removed the [ClassInterface(ClassInterfaceType.AutoDual)] from the classes, I could still invoke the overloaded methods in this way, thus avoiding the Wrong number of arguments or invalid property assignment error.

My question is: is this behavior - appending numeric suffixes to the member names - stable? documented? dependable?

A: 

In my experience, having interop generate Method, Method_1, Method_2, etc. is normal and stable but not really desirable. It's annoying that overloads don't cross the Managed/Unmanaged boundary. Instead of having it arbitrarily add a numeric suffix to my methods, I try to refactor the COM-Visible methods into separate methods with unique names so it's more obvious to the COM consumer what is being called.

C-Pound Guru
+2  A: 

COM does not support method overloading, so .NET COM Interop layer has to improvise. I'm not sure if name mangling as you described as documented anywhere, but even if it is, I don't think that using it is a good idea - it's still pretty inconvenient API for COM users. If you want to expose your classes to COM, the best way is to write a distinct COM-friendly [ComVisible] interface, and hide the class itself. The correct way to handle overloads in a COM-friendly way would be have a single method with some [Optional] arguments (and delegate to your corresponding .NET overloads).

Pavel Minaev