【发布时间】:2016-09-12 15:57:45
【问题描述】:
我正在编写一个 C# 应用程序来调用第三方 VB6 DLL。我在 References->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 的这个方法时,我得到了错误:
错误:试图读取或写入受保护的内存。这通常是一个 指示其他内存已损坏。
是什么原因,有什么解决办法?
注意,我无法更改 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 方法->.NET DLL->使用 ERP 供应商发布的 COM DLL 及其数据类(结构/UDT)。
如何调试内存错误?
【问题讨论】:
-
会不会是一些子结构需要'new'ing以及最高级别的?祝你好运,你有一个棘手的问题。
-
我尝试对每个成员结构使用 new,并检查它们是否依次具有其他结构。我仍然得到同样的错误。初始化接口类型 VBA.Collection 的成员的正确方法是什么?我尝试使用新的 VBA.CollectionClass。但我收到另一个错误:错误:检索具有 CLSID {A4C4671C-499F-101B-BB78-00AA00383CBB} 的组件的 COM 类工厂失败,原因是以下错误:80040154。 ------------- --------------
-
您是从 64 位 .net 应用程序调用 32 位 com dll 吗?
-
@AllSolutions 尝试在 C# 中定义一个静态类并将StandardModuleAttribute 应用到它。
-
@AllSolutions 忘记我之前的评论,您使用的是 COM 互操作,而不是 P/Invoke。不过,我仍然相信您的问题是 C# 和 VB6 之间的编组和/或共享内存。如果 UDT 将 VBA 集合作为字段,您可能需要像 link 这样的实现。不过,我不确定如果 VB6 尝试通过添加/删除成员来修改集合会发生什么(谁将拥有支持集合的内存??)
标签: c# dll vb6 com-interop user-defined-types