The North Face of Mount Everest

Home 
Photos 
Travel 
Technology 
Blog 
About 
  

Calling a .net (C#) dll from a COM Client (VB6)





C# dll code changes

In order to expose a C# class to a VB6 client very few changes to your C# code are required.

The first change is to add a "using" directive in order to use the COM Interop services:

     using System.Runtime.InteropServices;

Next we need to add the following attribute to the class definition. This attribute signifies that class should be visible to COM:

     [System.Runtime.InteropServices.ComVisible(true)]

We also need to add another attribute:

     [ClassInterface(ClassInterfaceType.AutoDual)]

Note that Microsoft strongly warn against using the value of "AutoDual". This is due to the usual COM limitations of version compatibility, aka DLL Hell! (see this Microsoft article for more details).

And finally .net classes which are exposed to COM must provide a public default constructor.


Registering your .net dll

The VB6 COM client needs to determine the exposed methods, properties and events of our .net dll. The COM runtime reads the registry to do this.

COM requires that information such as CLSIDs, IIDs, and ProgIDs etc. to be present in the registry, BUT .net assemblies are not registered, therefore they do not place entries into the registry!

Therefore we need to produce COM compatible registry keys for our .net dll in order for the COM runtime to use our dll (you cannot use regsvr32 to register a .net component).

There are two .net specific tools that we can use: tlbexp.exe and regasm.exe

Regasm.exe will register the type library and generate the required type library files (the "/tlb" option on regasm does the same job as tlbexp), therefore you can just use regasm and forget about tlbexp.

Regasm is found in the .net framework directory, generally C:\Windows\Microsoft.NET\Framwork\vXXX where XXX is the version of the .net framework that you are using. Add this path to you path variable if it does not exist.

Now, you can run regasm and register you .net dll:

     regasm.exe mydll /tlb:com.mydll.tlb


Examining the registry

Launch regedit and you will see that under HKEY_CLASSES_ROOT there is an entry for our .net class which, like any other COM class, contains a \CLSID subdirectory which maps to the CLSID of the class. Don't forget that you can manually specify the GUID value, if you don't then regasm will generate one automatically for you.

Now check out the registry entry for HKEY_CLASSES_ROOT\CLSID\"your GUID" subdirectory . This entry contains the usual COM information, but note that the InProcServer32 points to mscoree.dll rather than your dll! mscoree.dll is the .net runtime dll, therefore when you call your .net dll from COM the .net runtime will be called and it will be responsible for locating and loading your COM dll.


Activation from COM

To summarise, when a COM client calls a .net dll the following happens:

  • The COM runtime resolves the CLSID of the dll (using the registry)
  • The COM runtime looks at the value in \InProcServer32 and finds mscoree.dll
  • The CLSID is passed into mscoree.dll
  • The .net runtime (mscoree.dll) then searches for the .net assembly
  • The .net assembly is launched

Note that COM aware .net assemblies are generally located in the GAC, although it could reside in the same directory as your COM application.


Building your VB6 COM client

Now that your .net dll is registered for use by COM you can now reference it from your VB6 project.







© Andrew Sinclair 2009 [andy@andrewsinclair.co.uk]