从 .NET 调用具有复杂结构的 Win32 DLL
我已将旧的 VB6 组件升级到 .NET。该组件调用了另一个 Win32 组件,具有以下类型结构:
Public Type DDPARAMS
bAddressFlag As String * 1
bCompanyFlag As String * 1
bNameFlag As String * 1
bPremiseFlag As String * 1
..etc
我无法引用此 Win32 DLL,因为它不是 COM DLL,因此 .NET 无法自动为我创建任何互操作。
我有 Win32 DLL 的原始源代码(用 C 编写),结构在这里定义为:
typedef struct tagDDPARAMS
{
BYTE bAddressFlag;
BYTE bCompanyFlag;
BYTE bNameFlag;
BYTE bPremiseFlag;
BYTE sPremiseThreshold[3];
etc.
当我升级 VB6 组件时,为该结构生成的 .NET 代码为:
Public Structure DDPARAMS Public bAddressFlag() As Char
<VBFixedString(1), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=1)> Public bCompanyFlag() As Char
<VBFixedString(1), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=1)> Public bNameFlag() As Char
<VBFixedString(1), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=1)> Public bPremiseFlag() As Char
<VBFixedString(3), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=3)> Public sPremiseThreshold() As Char
<VBFixedString(3), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=3)> Public sLooseThreshold() As Char
等。
但是,当我运行此代码时,出现以下错误:
无法封送类型,因为嵌入数组实例的长度与布局中声明的长度不匹配.
我已经用谷歌搜索了一遍,但没有任何想法 - 任何帮助都是值得赞赏的。
更新:我尝试了下面的建议,并将 ByValArray 更改为 AnsiBStr (一字节字符串),现在得到以下信息:
“无法编组类型为“DDRECORD”的字段“sTown”:无效的托管/非托管类型组合(数组)字段必须与 ByValArray 或 SafeArray 配对。”
非常感谢 邓肯
I have upgraded an old VB6 component to .NET. This component made a call to another Win32 component, with the following type structure:
Public Type DDPARAMS
bAddressFlag As String * 1
bCompanyFlag As String * 1
bNameFlag As String * 1
bPremiseFlag As String * 1
..etc
I cannot reference this Win32 DLL as it is not a COM DLL, so .NET can't create any interop for me automatically.
I have the original source for the Win32 DLL (written in C), and the struct is defined here as:
typedef struct tagDDPARAMS
{
BYTE bAddressFlag;
BYTE bCompanyFlag;
BYTE bNameFlag;
BYTE bPremiseFlag;
BYTE sPremiseThreshold[3];
etc.
When I upgrade the VB6 component, the .NET code generated for the struct is:
Public Structure DDPARAMS
Public bAddressFlag() As Char
<VBFixedString(1), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=1)> Public bCompanyFlag() As Char
<VBFixedString(1), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=1)> Public bNameFlag() As Char
<VBFixedString(1), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=1)> Public bPremiseFlag() As Char
<VBFixedString(3), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=3)> Public sPremiseThreshold() As Char
<VBFixedString(3), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=3)> Public sLooseThreshold() As Char
etc.
However, when I run this code, I get the following error:
Type could not be marshaled because the length of an embedded array instance does not match the declared length in the layout.
I have googled and googled and am out of ideas - any help is appreciated.
UPDATE: I tried the suggestion below and changed ByValArray to AnsiBStr (one byte string) and now get the following:
"Cannot marshal field 'sTown' of type 'DDRECORD': Invalid managed/unmanaged type combination (Arrays fields must be paired with ByValArray or SafeArray)."
Thanks a lot
Duncan
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看来你的声明混淆了。检查 UnmanagementType,也许这可以帮助您找到正确的类型。我假设 bAddressFlag 在 VB 中应该是 Byte(而不是 char),并且应该使用 UnmanagementType.U1 进行声明。
但这只是一个猜测。
It seems that your declaration is mixed up. Check UnmanagedType, maybe this helps you find the proper types. I would assume that bAddressFlag should be Byte in VB (instead of char) and should be declared with UnmanagedType.U1 for example.
This is just a guess though.