将 vb6 类型转换为 VB.net 或 C# 结构

本文关键字:结构 net VB vb6 类型转换 | 更新日期: 2023-09-27 18:36:06

我正在将最初用 vb6 编写的应用程序转换为 vb.net。此应用程序执行的操作之一是将"Type"对象发送到 dll。我尝试将类型转换为结构并 p/调用 dll,但它似乎不起作用。我已经被困了一个星期,任何帮助将不胜感激

这是该类型的 VB6 代码

'Define WICS Communications Control Block (CCB).
Type WicsCCBType ' Create user-defined type.
    CCBNum As String * 1
    CCBVer As String * 1
    Resp1  As String * 4
    Resp2  As String * 4
    PLUA   As String * 8
    LLUA   As String * 8
    Mode   As String * 8
    ReqMax As String * 5
    ResMax As String * 5
End Type      

这是DLL的称呼方式

Private Declare Sub WICSRASP Lib "wicsrasp.dll" (MyWicsCCB As WicsCCBType)
WICSRASP MyWicsCCB

这是我用 vb.net 尝试的,但它不起作用

'Define WICS Communications Control Block (CCB).
    <System.Runtime.InteropServices.StructLayoutAttribute( _
            System.Runtime.InteropServices.LayoutKind.Sequential, _
            CharSet:=System.Runtime.InteropServices.CharSet.[Unicode])> _
    Structure WicsCCBType ' Create user-defined type.
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=1)> Dim CCBNum As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=1)> Dim CCBVer As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=4)> Dim Resp1 As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=4)> Dim Resp2 As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=8)> Dim PLUA As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=8)> Dim LLUA As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=8)> Dim Mode As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=5)> Dim ReqMax As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=5)> Dim ResMax As String
    End Structure

这就是我试图称之为它的地方

<System.Runtime.InteropServices.DllImportAttribute("C:'windows'system32'wicsrasp.dll")> _
    Public Shared Sub WICSRASP(
                    ByRef CCB As WicsCCBType,
                    ByRef Request As DAWicsRequestType,
                    ByRef Response As DAWicsResponseType)
    End Sub
 Dim CCB As New modWICSDiary.WicsCCBType()
 CCB.CCBNum = "B"
            CCB.CCBVer = "2"
            CCB.LLUA = "        "
            CCB.Mode = "CICSMO2 "
            CCB.ReqMax = "2100 "
            CCB.ResMax = "2100 "
            CCB.Resp1 = "0   "
            CCB.Resp2 = "0   "
            CCB.PLUA = "WICSPLU "
  NativeMethods.WICSRASP(CCB)

至于值,相同的值适用于 vb6 类型

再次提前感谢您

将 vb6 类型转换为 VB.net 或 C# 结构

我不知道OP是否已经解决了这个问题,但这是我的看法。

VB6 中 UDT 中的固定长度字符串不是编组为指针,而是内联到结构中。 此外,VB6 在编组之前将 Unicode 转换为 Ansi。 VB6 使用 4 字节对齐。

该类型将在内存中用填充来查找此内容,在插图中,每个连续字段都命名为 A 到 I,并且由于对齐,_ 是填充字节。

CCBNum As String * 1     
|
|+-CCBVer As String * 1     
||
||  Resp1  As String * 4
||  |
||  |   Resp2  As String * 4     
||  |   |
||  |   |   PLUA   As String * 8     
||  |   |   |
||  |   |   |       LLUA   As String * 8     
||  |   |   |       |
||  |   |   |       |       Mode   As String * 8     
||  |   |   |       |       |
||  |   |   |       |       |       ReqMax As String * 5     
||  |   |   |       |       |       |
||  |   |   |       |       |       |       ResMax As String * 5 
||  |   |   |       |       |       |       |
||  |   |   |       |       |       |       |
VV  V   V   V       V       V       V       V
AB__CCCCDDDDEEEEEEEEFFFFFFFFGGGGGGGGHHHHH___IIIII___

因此,CharSet 应该是 Ansi,StructAlign 应该是 4。 使用ByValTString很好,SizeConst的使用也是如此。

VB6 会将所有这些字符串元素"封送"为 ANSI 字符串。相应地更改 Vb.Net 编组代码。

  • 尝试UnmanagedType.LPStr这些MarshalAs属性?
  • 尝试将字符集从 Unicode 更改为 Ansi?
  • 试试Pack=4 StructLayoutAttribute

有用的链接,解释了VB6 Declare所做的假设

VB6 使用了 BSTR,不是吗?你不应该担任BSTR吗?