Click here to Skip to main content
13,148,107 members (72,716 online)
Rate this:
Please Sign up or sign in to vote.
See more:
I have written a class library using Visual C++ 2005 (CLR, old syntax). It is working fine and can be used from all .NET IDE's, including VB, C# and C++, exposing classes with methods and properties, enumerations...

Now I want to use it from VB6 and I understand that I need to somehow make it COM compatible.

I have read different things, some about COM Interop project properties, others mentioning the ComVisibleAttribute, others Type Libraries...

So far my different attempts have lamentably failed (no suitable options in the IDE, no TLB file being generated, the ComVisibleAttribute syntax raises an "Attribute Not Found" error...)

I am lost in the jungle and I need some guidance here. Who can help me ?
Posted 24-Feb-13 23:18pm
Updated 8-Mar-13 3:08am
CHill60 25-Feb-13 5:37am
Have you seen this article
Chris Reynolds (UK) 25-Feb-13 5:39am
That's the article I used when I did this recently and it did the trick for me.
YvesDaoust 25-Feb-13 5:46am
Of course. None of it seems applicable to my case. Specifically: "5.Click Configuration Properties, and then click the Build node": there is no Build node in the configuration properties of VC2005; I coundn't find any equivalent (same about "Compile"); "Use the ComVisibleAttribute attribute": the syntax [CombisibleAttribute(true)] genrerates a compilation error; "The /tlb: switch generates and registers a type library": no, I don't see any TLB file generated.

This article makes me believe that what I want to achieve is possible and at the same time sticks me deeply.
CHill60 25-Feb-13 6:01am
In that case have you seen this tool
YvesDaoust 25-Feb-13 6:05am
Just seen it and tried it. Things just a little more obscure now...
YvesDaoust 25-Feb-13 6:03am
Something rather puzzling:
regasm mVizNET.dll /tlb says:

RegAsm : error RA0000 : Failed to load 'mVizNET.dll' because it is not a valid .NET assembly

I can't understand this, as the file mVizNET.dll does work; in particular, it can be referenced by a project and the Object Browser views it seamlessly. So this must be a valid assembly, mustn't it ?
YvesDaoust 25-Feb-13 6:29am
First progress: ComVisibleAttribute requires a "using namespace System::Runtime::InteropServices;" clause.
Chris Reynolds (UK) 25-Feb-13 7:20am
Also there is the 'Register for COM interop' option in Project Settings|Build tab which should be ticked
YvesDaoust 25-Feb-13 8:07am
As I already explained, there is no Build tab in the projects settings, I am using VC++ to build the assembly, not C# nor VB. I didn't see any option similar to "Register for COM Interop".
Sergey Alexandrovich Kryukov 25-Feb-13 12:20pm
Listen to a good advice: forget it.
Sergey Alexandrovich Kryukov 25-Feb-13 12:19pm
This is a really bad idea. You will sooner switch to .NET completely...
It's possible but not easy; there is a COM way, but it actually contaminates the system with registration of components; why?
YvesDaoust 25-Feb-13 12:30pm
Dropping this is not an option, it is required by customers. The alternative is to rewrite the whole stuff as ActiveXs, which I want to avoid.

What do you mean by "contaminates the system" ?
Sergey Alexandrovich Kryukov 25-Feb-13 14:55pm
Contaminates? OK. Executable module A uses module B; that would be fine. But with COM, the situation is different. B is registered as COM component, system-wide, through some Registry records, but it is used only by A. This is disastrous approach: system is contaminated.

The only straight and clear way is: forget COM, forget VB6, use .NET.
YvesDaoust 25-Feb-13 14:24pm
Second progress: need to find the right version of regasm ! (I had several of them on my machine). Shame on MS for not warning about version incompatibilities.
Sergey Alexandrovich Kryukov 25-Feb-13 14:52pm
Not "used from all .NET IDEs", but "by all .NET assemblies". If this is not a typo, you probably don't understand the basics...
YvesDaoust 26-Feb-13 6:11am
Next progress: RegAsm seems to be case unsensitive as it raises an "ambiguous name" error in case two identifiers are identical except for casing. Once this is avoided, a TLB file is generated.
YvesDaoust 26-Feb-13 6:18am
Next trap, next solution: it is not enough to raise the ComVisible attribute, as no class method will be exposed (the class data members are). Now we need to let the compiler generate the proper interface definitions with ClassInterfaceAttribute(ClassInterfaceType::AutoDual).
Rate this: bad
Please Sign up or sign in to vote.

Solution 1

COM Interop works fairly well once you have tamed it.

1) Avoid static class members, as these are not supported by COM. Also avoid identifiers that just differ by casing.

2) Add the following attribute to the assembly (in AssemblyInfo.cpp):
[assembly:ClassInterfaceAttribute(ClassInterfaceType::AutoDual)]; // This will let VB6 pre-load the interface definitions
Uses the System::Runtime::InteropServices namespace.

3) Create the corresponding Type Library file and register it using the regasm command as a post-build event (project Properties -> Build Events -> Post-Build Events -> Command Line):
regasm "$(TargetPath)" /tlb

Build the class library from VC++, let MyLib.dll. The file MyLib.tlb will also be built.

4) Under VB6, register the reference to the Type Library: Project -> References..., then browse to the .tlb file and check the checkbox next to the new entry in the list.

5) From then on, the Object Browser (F2) will show you the contents of the library, and autocompletion will be performed by the editor.

6) Copy MyLib.dll next to the VB6.exe executable to work from the IDE. You will also need to copy it next to the compiled application if you plan to Make one.

7) Instantiating a class is achieved with:
Dim MyInstance As MyLib.MyClass
Set MyInstance = New MyLib.MyClass

You're done !

You may experience malfunctions and error messages at some stages. These can be due to dlls (run-time libraires, .NET framework or MyLib.dll) not being found in the search path.

Datatypes unsupported by COM also raise issues.
Rate this: bad
Please Sign up or sign in to vote.

Solution 2

You can find this article useful to solve your problem although it if of C++ instead of vb6

Calling Managed .NET C# COM Objects from Unmanaged C++ Code[^]
YvesDaoust 4-Mar-13 7:13am
Thanks for the suggestion.

I have now completed a solution that does not require programming (well, a single line of code), and... works, so I am adopting it :)
MatsGF 14-Jan-14 6:21am
Can you describe that solution that didn't involve programming?
YvesDaoust 14-Jan-14 6:31am
This is Solution 1. All I had to change in my code was inserting the line
[assembly:ClassInterfaceAttribute(ClassInterfaceType::AutoDual)]; // This will let VB6 pre-load the interface définitions

But of course, all the class wrapping code needs to be there as well.
MatsGF 14-Jan-14 8:37am
I was hoping to find a solution that didnt include COM-objects since i wanted to get rid of the registration.
YvesDaoust 14-Jan-14 9:00am
This seems to be doable:

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy |
Web01 | 2.8.170924.1 | Last Updated 8 Mar 2013
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100