Tuesday, November 06, 2007

C#->VB6->C# Sucks

The current project I am working on is erm, interesting. The scope of the project is to replace VB business logic, with C# and SQL Server. The major caveat is that the VB front end MUST stay intact. Not only intact but untouched.

Fun fun.

Most things just work out of the box. Obviously all classes must be exposed with [ComVisible(true)] attributes and given a GUID. Even though Microsoft states that you shouldn't =, we also had to use the AutoDual visibility attribute to get VB to see the public methods.

The VB code we have to interface to uses classes with property method indexers. These are probably called something else in VB, But I call it this. These look something like this (going OTOH so might get syntax wrong)

Public Property Let Reminder(index as Integer) as String
Public Property Set Reminder(index as Integer) as String

instead of being marshaled as

public string[] Reminder
{
get;
set;
}

as you might think, this gets Marshaled as

public string get_Reminder(short __p1);
public void set_Reminder(short __p1, string __p2);

which is of course correct. This is not a major, but the VB code does need changing. Also if the underlying VB array that the properties refer to are not zero based then the C# code then has to take this into consideration when dealing with the index.

oh and any normal VB property that is assigned with ByRef or more to the point, with ByVal not added then the properties get marshaled as above.

Like I said fun fun.

Heres the "killer feature" though. If you are doing Unit testing in C# of the VB Business logic that includes your C# that includes VB arrays that are marked by ref, well it won't work. It falls down in the re-marshaling back into C#. (Don't ask).

But with a bit of reflection foo it is possible.

First you have to get the type using

Type t = Type.GetTypeByProgID("mydll.dll");
object objectInstance = Activator.CreateInstance(t);

then we just simply go InvokeMethod with the Class Name, Method Name and any method arguments in an object array.

I'll post the code - don't have it on hand at the moment.

Anyway, if you can avoid COM and .NET do so. Well VB frontend to C# code anyway...

No comments: