Hidan
Hidan

Reputation: 357

Marshal structure to pointer then pointer to unicode string VB.Net

Our client has a requirement to move data from a structure into a string so that it can be shipped off to the mainframe. Our process coming in is basically marshaling the data from string into the structure, this part was easy...

I'm trying to do the reverse now and am running into some difficulties. Here is the test structure I'm working with.

 <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
Public Structure Contact
    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=50)> _
    Public Address As String
    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=20)> _
    Public FirstName As String
    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=20)> _
    Public LastName As String
    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=12)> _
    Public PhoneNumber As String
End Structure

and here is the test method I'm using:

 Public Sub TestContactToString()

    Dim contact As New Contact

    contact.Address = "123 Main st."
    contact.FirstName = "Bob"
    contact.LastName = "Builder"
    contact.PhoneNumber = "613-828-1233"

    Dim unmanagedAddress As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(contact))

    Marshal.StructureToPtr(contact, unmanagedAddress, True)

    Dim result As String = Marshal.PtrToStringUni(unmanagedAddress)

    Marshal.FreeHGlobal(unmanagedAddress)
    unmanagedAddress = IntPtr.Zero

End Sub

Right now the result variable is only getting the first field in the structure "Address"... It looks as thought the pointer many not have enough space allocated? Wondering how I would go about getting the rest of the data into the string...

Any help would be greatly appreciated!

Thank you.

Upvotes: 0

Views: 1927

Answers (1)

Hans Passant
Hans Passant

Reputation: 941545

Well, yes, this is the expected outcome. Marshal.PtrToStringUni() will terminate on an embedded zero, the string terminator for strings in the C language. Which will be present in the struct since the strings won't fill the entire field. And are generated by Marshal.StructureToPtr() because it assumes a C program will read the struct.

You used a cannon to kill a mosquito, use String.PadRight() instead.

Upvotes: 1

Related Questions