我正在编写一个 C# 应用程序来调用第三方 VB6 DLL。我在“引用”->“COM”选项卡中添加了对 VB6 DLL 的引用。
DLL 中的特定方法将 VB6 UDT(用户定义类型)作为参数。
此 UDT 在为 COM 自动生成的 .NET 包装器中显示为一个结构。该结构有很多子 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 的这个方法时,出现错误:
Error: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
是什么原因,如何解决?
请注意,我无法更改 VB6 DLL,因为我没有它的源代码。我正在使用 VS 2005。
编辑 1:
这是一个完整的背景:
有一款本地开发的ERP产品,支持使用VB6进行插件开发。它有一个配置文件,指定要加载的附加 DLL 的名称。然后,这些插件会显示在 ERP 应用程序的菜单中。单击菜单时,ERP 调用名称为 StartAddOn() 的函数,该函数应存在于 VB6 DLL 中。
我想用 C# 开发插件,所以我开发了一个简单的 VB6 插件,它有一个 StartAddOn 方法,该方法又将控制权传递给我的 .NET DLL。
.NET DLL 使用 ERP 公开的业务类,并来回传递数据对象。在 .NET DLL 中,我添加了对 ERP 供应商发布的 DLL 的 COM 引用。
所以架构是这样的: ERP->VB6 AddOn with StartAddOn 方法->.NET DLL->使用 ERP 供应商发布的 COM DLL 及其数据类(结构/UDT)。
如何调试内存错误?
最佳答案
结构是什么样的?自从我进行任何认真的 VB6 开发以来已经有一段时间了,但我记得在不同语言之间调用时有时会绊倒我的一件事是 VB6 坚持对所有结构进行双字对齐。因此,例如,如果您在中间混合了一些字节值,它将插入填充,以便所有值在偶数 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/
关于c# - 从 C# 调用具有复杂用户定义类型 (UDT) 的 VB6 DLL 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37261070/