从 .NET 调用具有复杂结构的 Win32 DLL

发布于 2024-09-24 18:39:19 字数 2009 浏览 3 评论 0原文

我已将旧的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

毁虫ゝ 2024-10-01 18:39:19

看来你的声明混淆了。检查 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文