3
votes

I'm am doing a COM-interop project. Substituting some VB and C++ ATL COM projects with C# and .NET Interop. When i define enumerations in .NET and they are made ComVisible, they get exposed as Typelib.EnumType_EnumValue enstead of just Typelib.EnumValue. The typelib exporter does this to ensure that the value names are unique. But i know that all my enum's are unique, so i don't want the underscores. Also there is a lot of client code that needs alteration if i don't get rid of the underscores.

To find a solution to this problem, i have defined the enum's in an IDL-file and creating a typelib and .Net interop from this.

[
  uuid(64893FD4-359D-46B9-BC1E-48C055796104),
  version(1.0),
  helpstring("ABC"),
  helpfile("AAA.chm"),
  helpcontext(0x00000001)
]

library EnumTypeLib
{
    importlib("stdole2.tlb");
    typedef [uuid(8FF85069-C4E2-4540-A277-4C0F3C19B807), helpstring("MyEnum"), helpcontext(0x00000066)]
    enum MyEnum {
        Value1 = 0,
        Value2 = 1,
    } MyEnum;
};

I create a typelibrary with MIDL.exe which produces a tlb-file.

And i create an assembly with the tlbimp.exe. signing the assembly with the same key as the other Interop assemblies.

tlbimp OpenStructureAdapterEnum.tlb /keyfile:KeyFile.snk

Then i register the assembly with regasm.exe This assembly looks fine and contains the enum without underscores. But the problem is that a can't see the COM-library from OLE/COM Object Viewer or from VBA or VB6. And when i reference the enum from another COM-exposed assembly, the part of the interface containing references to the enum, gets exposed as resticted methods.

[restricted] void Missing7();
[restricted] void Missing8();
[restricted] void Missing9();
[restricted] void Missing10();

How can i create a COM library containing only enums (without underscores) and referencing these from other .net Interop assemblies?

2

2 Answers

2
votes

To answer your last question first. What you are wanting is a TypeLib not a COM library. Where a COM interface is a bunch of code and function pointers, a TypeLib is the map for interacting with those pointers (along with defines and enums and a bunch of other stuff). Only when they come together is there a COM library. Since there is no COM interface, you cannot have a COM library.

Microsoft has provided an example on how to create a TypeLib without an interface. It is a very similar to the one you have described. As you'll notice, there's no COM interface in it; and because of this, it has to stay a lowly TypeLib.

The next problem is the .NET assembly. When you use TlbImp.exe to import the enums into your code, that allows you to use those enums within your code - inside your assembly. That is the limit of what you can do with the enums. You cannot export those enums because they don't belong to your .NET code. The enum is owned by the TypeLib. Your .NET code has permission to use the enum, but it cannot claim to own the enum.

Finally, to answer your first question. You need to use the features provided with .NET. It has the ability to define enums and export them and make them visible from COM. While I understand the frustration over naming convention, this is not something that you should try to work around or bypass. As you have seen, attempting to bypass this minor problem with the naming convention has caused major problems, effectively making your new code unusable.

2
votes

I have done this:

In .NET, I created a COM visible library named PermissionControlLib with an enum like this:

public enum NetOperations
{
   Oper1,
   Oper2,
   Oper3
}

In VB6, I've created another enum like this:

Public Enum VBOperations
   Oper1=NetOperations.NetOperations_Oper1,
   Oper2=NetOperations.NetOperations_Oper2,
   Oper3=NetOperations.NetOperations_Oper3
End Enum

Usage:

Dim ud as PermissionControlLib.IUser
Set ud = New User
Dim b as Boolean
b = ud.HasPermissionInOperation(VbOperations.Oper1)