Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a VB6 DLL function with a complex User Defined Type (UDT) from C#

I am writing a C# application to call a third party VB6 DLL. I have added reference to the VB6 DLL in the References->COM tab.

A particular method in the DLL takes a VB6 UDT (User Defined Type) as a parameter.

This UDT is shown as a struct in the auto generated .NET wrapper for COM. The struct has lots of child UDTs / structs as well as members of type VBA.Collection (as shown by .NET metadata). It also has regular data types like string, short, double, int, etc.

I am initializing this struct in my C# code as:

udtEmployee udtEmpData = default(udtEmployee);

I also tried

udtEmpData = new udtEmployee();

If I do not initialize it using default or new, I am not able to compile my C# code, as the compiler complains about use of unassigned variable.

I need to pass this struct as reference. I am doing it like this:

clsEmployee.SetData(ref udtEmpData);

While calling this method of the VB6 DLL, I am getting error:

Error: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

What is the reason and what is the solution?

Note, I can not change the VB6 DLL as I do not have its source code. I am using VS 2005.

EDIT 1:

Here is a complete background:

There is a locally developed ERP product, which supports add-on development using VB6. It has a configuration file, which specifies the names of add-on DLLs to be loaded. These addons are then displayed in a menu in the ERP application. On menu click, the ERP calls a function with the name StartAddOn() which should be present in the VB6 DLL.

I wanted to develop add-on in C#, so I developed a simple VB6 addon with a StartAddOn method, which in turn passes control to my .NET DLL.

The .NET DLL uses the business classes exposed by the ERP, and passes data objects to and fro. In the .NET DLL, I have added a COM reference to the DLL published by the ERP vendor.

So the architecture is like this: ERP->VB6 AddOn with StartAddOn method->.NET DLL->uses COM DLL published by the ERP vendor and its data classes (structs / UDTs).

How can I debug the memory error?

like image 807
AllSolutions Avatar asked May 16 '16 18:05

AllSolutions


1 Answers

What does the struct look like? It's been a while since I did any serious VB6 development, but one of the things I remember tripping me up sometimes when calling between languages was VB6's insistence on dword-aligning all of it's structures. So for example if you have some byte values mixed in the middle, it will insert padding so all the values align on an even 4 byte boundary. Consider the following:

Type MyType
    A As Long
    B As Byte
    C As Long
End Type

In memory, there will be 3 bytes of unused space between B and C. Of course if C# is not performing the same padding, it can throw your values off and cause all sorts of chaos.

With some compilers (such as C) it is possible to set a compiler switch to use this type of alignment. I don't know if C# has anything similar. If not, the solution is to insert some dummy fields of the appropriate size in to your struct on the C# size.

Here's an article which provides more information about how VB6 aligns UDTs: http://www.developerfusion.com/article/3367/copymemory-and-arrays-proper-use/4/

like image 52
Steve In CO Avatar answered Oct 17 '22 02:10

Steve In CO