user889829
user889829

Reputation: 418

Convert vb6 Type to VB.net or C# Struct

I am converting an application originally written in vb6 to vb.net. One of the things this application does is that it sends a “Type” object to a dll. I tried converting the type to a structure and p/invoking the dll but it does not seem to work. I’ve been stuck for a week any help would be really appreciated

here is the vb6 code for the type

'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      

and here is how the dll is called

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

this is what i tried with vb.net but it is not working

'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

and here is where i tried to call it

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

As to the values, the same values work for the vb6 type

again thank you in advance

Upvotes: 4

Views: 1729

Answers (3)

tcarvin
tcarvin

Reputation: 10855

I don't know if this has been solved by the OP yet, but here's my take on it.

Fixed-length strings inside UDTs in VB6 are not marshalled as pointers but are inlined into the structure. Additionally, VB6 converts Unicode to Ansi before marshalling. And VB6 uses 4 byte alignment.

The type will look this this in memory with the padding, with each successive field being named A through I in the illustration, and _ being a pad byte due to alignment.

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___

Therefore the CharSet should be Ansi, the StructAlignment should be 4. The use of ByValTString is fine, as is the use of SizeConst.

Upvotes: 1

SSS
SSS

Reputation: 5403

VB6 used BSTRs, didn't it? Shouldn't you marshal as BSTR?

Upvotes: 0

MarkJ
MarkJ

Reputation: 30398

The VB6 will "marshal" all those string elements as ANSI strings. Change the Vb.Net marshalling code accordingly.

  • Try UnmanagedType.LPStr in those MarshalAs attributes?
  • Try changing the CharSet from Unicode to Ansi?
  • Try Pack=4 in the StructLayoutAttribute?

Useful link which explains the assumptions made by the VB6 Declare

Upvotes: 1

Related Questions