使用C#中的复杂用户定义类型(UDT)调用VB6 DLL函数

时间:2016-05-16 18:46:34

标签: c# dll vb6 com-interop user-defined-types

我正在编写一个C#应用程序来调用第三方VB6 DLL。我在References-> COM选项卡中添加了对VB6 DLL的引用。

DLL中的特定方法采用VB6 UDT(用户定义类型)作为参数。

此UDT在自动生成的COM包装器中显示为结构。该结构具有许多子UDT /结构以及VBA.Collection类型的成员(如.NET元数据所示)。它还有常规数据类型,如string,short,double,int等。

我在C#代码中初始化此结构为:

udtEmployee udtEmpData = default(udtEmployee);

我也试过

udtEmpData = new udtEmployee();

如果我没有使用default或new初始化它,我无法编译我的C#代码,因为编译器抱怨使用未分配的变量。

我需要传递这个结构作为参考。我是这样做的:

clsEmployee.SetData(ref udtEmpData);

在调用VB6 DLL的这个方法时,我收到错误:

  

错误:尝试读取或写入受保护的内存。这通常是一个   表明其他内存已损坏。

原因是什么,解决方案是什么?

注意,我无法更改VB6 DLL,因为我没有源代码。我正在使用VS 2005。

编辑1:

这是一个完整的背景:

有一个本地开发的ERP产品,它支持使用VB6进行附加开发。它有一个配置文件,它指定要加载的附加DLL的名称。然后,这些插件将显示在ERP应用程序的菜单中。在菜单上单击,ERP调用名为StartAddOn()的函数,该函数应存在于VB6 DLL中。

我想在C#中开发附加组件,因此我使用StartAddOn方法开发了一个简单的VB6插件,该方法又将控制权传递给我的.NET DLL。

.NET DLL使用ERP公开的业务类,并来回传递数据对象。在.NET DLL中,我添加了对ERP供应商发布的DLL的COM引用。

所以架构是这样的: ERP-> VB6 AddOn with StartAddOn method-> .NET DLL->使用ERP供应商发布的COM DLL及其数据类(结构/ UDT)。

如何调试内存错误?

1 个答案:

答案 0 :(得分:3)

结构是什么样的?自从我做了任何严肃的VB6开发以来已经有一段时间了,但是我记得有时在语言之间进行调用时绊倒我的事情之一就是VB6坚持对所有结构进行dword-align。因此,例如,如果您在中间混合了一些字节值,它将插入填充,以便所有值在均匀的4字节边界上对齐。请考虑以下事项:

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

在内存中,B和C之间将有3个字节的未使用空间。当然,如果C#没有执行相同的填充,它可能会抛弃你的值并导致各种混乱。

对于某些编译器(例如C),可以将编译器开关设置为使用此类型的对齐方式。我不知道C#是否有类似的东西。如果没有,解决方案是在C#大小的结构中插入一些适当大小的虚拟字段。

这篇文章提供了有关VB6如何对齐UDT的更多信息: http://www.developerfusion.com/article/3367/copymemory-and-arrays-proper-use/4/