1

I am having a .NET COM assembly A consists of 3 classes say B, C and D. I use to refer this COM dll from my VB6 as A.B, A.C and A.D.

Recently when I tried to recompile my VB6 project, still I am able to reference A.B and A.C.

But class D is getting exposed as A.A_D in the VB6 Object browser. My question is why Class Name and Underscore is getting appended to class D.

I am using .NET framework 4.0 for DLL. Find below Pseudo Code for your reference. ProgID is not used. Instead direct reference to the object is used in VB6.

Class A : Configured as Class Library

Class B:

<ComClass(B.ClassId, B.InterfaceId, B.EventsId), ComVisible(True)> Public Class B

#Region "COM GUIDs"
    'All the real GUIDs/Interface/Events are replaced with zeros for code security purpose
    Public Const ClassId As String = "0000000-0000-0000-0000-000000000000"
    Public Const InterfaceId As String = "00000000-0000-0000-0000-000000000000"
    Public Const EventsId As String = "00000000-0000-0000-0000-000000000000"
#End Region

Class C:

<ComClass(C.ClassId, C.InterfaceId, C.EventsId), ComVisible(True)> Public Class C

#Region "COM GUIDs"
    'All the real GUIDs/Interface/Events are replaced with zeros for code security purpose
    Public Const ClassId As String = "0000000-0000-0000-0000-000000000000"
    Public Const InterfaceId As String = "00000000-0000-0000-0000-000000000000"
    Public Const EventsId As String = "00000000-0000-0000-0000-000000000000"
#End Region

Class D:

<ComClass(D.ClassId, D.InterfaceId, D.EventsId), ComVisible(True)> Public Class D

#Region "GUIDs"
    'All the real GUIDs are replaced with zeros
    Friend Const ClassId As String = "00000000-0000-0000-0000-000000000000"
    Friend Const InterfaceId As String = "00000000-0000-0000-0000-000000000000"
    Friend Const EventsId As String = "00000000-0000-0000-0000-000000000000"
#End Region

In OLEView Class D alone gets prepended with namespace A. Class B and C remains same. When I backtracked this DLL, namespace is getting prepended only after migrating to Framework 4. This problem seems to be similar to the one mentioned in prepending-namespace-to-typelib-coclass-name But the difference here is I am still using Visual Studio 2010 and I do not find

Embed Interop Types property

OLEView.exe Output

coclass D

[uuid(00000000-0000-0000-0000-000000000000),
version(1.0),
custom({00000000-0000-0000-0000-000000000000}, "A.D")]

coclass A_D {
    interface _Object;
    [default] interface _D;
    [default, source] dispinterface __D;
};

coclass B

[uuid(00000000-0000-0000-0000-000000000000),
version(1.0),
custom({00000000-0000-0000-0000-000000000000}, "A.B")]

coclass B{
   interface _Object;
   [default] interface _B;
   [default, source] dispinterface __B;
};
StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
KJG
  • 93
  • 9

1 Answers1

1

Without seeing the real class name for D its impossible to be certain. But a likely possibility is that the bare name D would conflict with something else and so the compiler (*) adds the assembly name to distinguish it.

If you want to confirm this you could load the .TLB file for your assembly in OLEView or some similar tool and inspect the IDL, which probably would show the same A_D name.

Another test would be to change D to almost anything else and recompile and see if that has any effect.

As noted in a comment using the [ProgId] attribute may be a way to force it to supply a more desirable name in the type library.

(* Not truly the compiler but the tools which generate the COM wrapper layer & the type library)

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
  • When i tried to get reference in Excel VBA, as you told the class name is shown as A.A_D. But in ildasm.exe tool it is just shown as A.D – KJG Feb 05 '20 at 17:27
  • 1
    ildasm is showing you the .NET name - not the name presented to COM – StayOnTarget Feb 05 '20 at 18:13
  • Ref: https://stackoverflow.com/questions/3940498/is-there-a-tool-for-exploring-testing-com-objects you can use a tool like OLEView or https://github.com/tyranid/oleviewdotnet/releases as an alternative. The file you want to inspect would be something like D.TLB (TLB for "type library") – StayOnTarget Feb 05 '20 at 18:15
  • Hello UuDdLrLrSs, Included OLEView output in my query. Also found similar question in Stackoverflow. But unable to find that solution in VS2010. Thanks – KJG Feb 06 '20 at 07:47
  • So where it says `coclass A_D` - this proves that it is the .NET build which is producing the "A_D" name. I don't know what "D" really is but does it conflict with some other known name, keyword, or something? Can you just add what D really is? – StayOnTarget Feb 07 '20 at 18:29
  • Sorry for late reply. Seems Name Space A is having reference to 3rd party library. Third party library has introduced new public class with name "D". Seems this is the reason .NET is adding A_D to avoid name clash. Even PROGID option in name space A.D, the class gets renamed to A.A_D. When we use separate UUIDs to differentiate the classes, they why .NET wants to still differentiate the class name adding namespace_ in prefix. Problem got solved after renaming A.D as A.renamedD (idifferent class name not clashing with other class name in referenced third party lbry). This issue can be closed. – KJG Feb 17 '20 at 13:02
  • 1
    That makes sense. I've found that the .NET tool which generates the COM Interface is somewhat rigid without allowing much customization. Hard to say "why" they chose to do it that way instead of some other approach or allowing you to have more control. If you export enums from C# to VB6 they have similar problems with naming. – StayOnTarget Feb 17 '20 at 14:01
  • Oh, to add: .NET code itself benefits from having namespaces which disambiguate names. But COM does not have namespaces, so the tools have much less flexibility in what names can be exported without clashes. That's not to say they could not do a better job than they do, in theory. But you are probably stuck with this. – StayOnTarget Feb 17 '20 at 14:03