Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: VB6 .NET
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 25-Feb-13 0:18am
Edited 8-Mar-13 4:08am
v3
Comments
CHill60 at 25-Feb-13 5:37am
   
Have you seen this article http://support.microsoft.com/kb/817248
Chris Reynolds (UK) at 25-Feb-13 5:39am
   
That's the article I used when I did this recently and it did the trick for me.
YvesDaoust at 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 at 25-Feb-13 6:01am
   
In that case have you seen this tool http://msdn.microsoft.com/en-us/library/h627s4zy.aspx
YvesDaoust at 25-Feb-13 6:05am
   
Just seen it and tried it. Things just a little more obscure now...
YvesDaoust at 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 at 25-Feb-13 6:29am
   
First progress: ComVisibleAttribute requires a "using namespace System::Runtime::InteropServices;" clause.
Chris Reynolds (UK) at 25-Feb-13 7:20am
   
Also there is the 'Register for COM interop' option in Project Settings|Build tab which should be ticked
YvesDaoust at 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 at 25-Feb-13 12:20pm
   
Listen to a good advice: forget it.
—SA
Sergey Alexandrovich Kryukov at 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?
—SA
YvesDaoust at 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 at 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.
—SA
YvesDaoust at 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 at 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...
—SA
YvesDaoust at 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 at 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
good
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.
  Permalink  
v10
Rate this: bad
good
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[^]
  Permalink  
Comments
YvesDaoust at 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 at 14-Jan-14 6:21am
   
Can you describe that solution that didn't involve programming?
YvesDaoust at 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 at 14-Jan-14 8:37am
   
Thanks!
I was hoping to find a solution that didnt include COM-objects since i wanted to get rid of the registration.
YvesDaoust at 14-Jan-14 9:00am
   
This seems to be doable: http://msdn.microsoft.com/en-us/library/fh1h056h.aspx

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

  Print Answers RSS
0 OriginalGriff 431
1 Afzaal Ahmad Zeeshan 184
2 /\jmot 176
3 Sergey Alexandrovich Kryukov 175
4 Marcin Kozub 175
0 OriginalGriff 8,344
1 Sergey Alexandrovich Kryukov 7,407
2 DamithSL 5,634
3 Maciej Los 5,024
4 Manas Bhardwaj 4,986


Advertise | Privacy | Mobile
Web01 | 2.8.1411023.1 | Last Updated 8 Mar 2013
Copyright © CodeProject, 1999-2014
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