Sunday, July 8, 2007

Visual Basic Fusion - Interfacing VB6 and .NET

This came to me in a MSDN Flash email. VB6 applications can actually use, with severe restrictions, .NET classes. The original article, in Spanish, can be found at: http://www.microsoft.com/spanish/msdn/latam/articulos/2007_06_18/default.aspx

VB6 has class modules, but does not support a true object model. Thus, .NET classes that want to be used from VB6 have restrictions.

Briefly:

1) There must exist a default (no parameter) constructor.
2) Probably the most difficult to bypass: data types are different in VB6 and .NET.
3) Static methods cannot be accessed.
4) Overloaded methods are arbitrarily appended numbers to their names so that they can be told from each other, when using .NET classes from VB6.
5) The assembly must be available in the Global Assembly Cache (GAC).

The solution proposed in the article consists of writing .NET wrapper classes for all .NET classes not abiding by those restrictions, and exposing these wrappers in turn to VB6. Therefore, such a wrapper class will have to add a default constructor if there is not one available (and defer true object creation adding an initializer method that takes the parameters originally intended for the constructor if needed), add methods that in turn call static methods so as for the call to seem to VB6 as being made from an instance of the object, add methods that rename overloaded methods to appropriate - and different - names, and over all, convert between data types as needed. I tend to think all methods will end up returning quite primitive data types, because if you have object composition in your .NET object model, how can you tell VB6 what the object you are returning from a method - supposing you did so - is mapped to in VB6? There is the possibility of using the Object data type, which according to the article is automatically converted between VB6 and VB.NET, still the question of whether this would do remains for me.

When these restriction-compliant classes are available in the GAC, they must be registered as COM objects so that they can be seen from VB6. This is done with the regasm command.

All in all, it does not seem like a simple task, but it could be useful in some cases when there is a legacy application and some very specific feature from .NET is needed.

1 comment:

Anonymous said...

One of the most effective uses of the technique you described is when you have a 3rd party object written in .NET that has to be accessed from a legacy VB6 or ASP application.

For example, I recently needed to use iTextSharp to allow PDF document merging from our legacy ASP application. I could not call this DLL directly from ASP or a VB6 COM+ object and recoding it where I could call it wasn't a good option. So, I wrote a VB.NET wrapper as described in your article that only exposed the functionality I needed. This allowed me to quickly add this functionality to our app with a minimal amount of coding.