从 C# 调用具有复杂用户定义类型 (UDT) 的 VB6 DLL 函数 [英] Calling a VB6 DLL function with a complex User Defined Type (UDT) from C#

查看:24
本文介绍了从 C# 调用具有复杂用户定义类型 (UDT) 的 VB6 DLL 函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

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

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

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

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.

我在我的 C# 代码中将这个结构初始化为:

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

udtEmployee udtEmpData = default(udtEmployee);

我也试过了

udtEmpData = new udtEmployee();

如果我不使用 default 或 new 对其进行初始化,我将无法编译我的 C# 代码,因为编译器会抱怨使用未分配的变量.

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);

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

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?

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

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

编辑 1:

这是一个完整的背景:

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

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.

我想用 C# 开发插件,所以我开发了一个带有 StartAddOn 方法的简单 VB6 插件,该方法又将控制权传递给我的 .NET 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.

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

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.

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

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).

如何调试内存错误?

推荐答案

这个结构是什么样子的?自从我进行任何认真的 VB6 开发以来已经有一段时间了,但我记得有时在语言之间调用时让我绊倒的一件事是 VB6 坚持双字对齐它的所有结构.因此,例如,如果您在中间混合了一些字节值,它将插入填充,以便所有值在偶数 4 字节边界上对齐.考虑以下几点:

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

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

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.

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

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.

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

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/

这篇关于从 C# 调用具有复杂用户定义类型 (UDT) 的 VB6 DLL 函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆