0

I have hex_data struct as output of a function of a DLL.

typedef struct hex_data
{
 USHORT usLength;
 LPBYTE lpbData;
 } HEXDATA

where lpbData is a pointer to the byte stream and usLength is the length of the byte stream pointed to by lpbData. Now I need to marshal this struct to a C# struct. What unmanged type I should use for lpbData in below struct definition:

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
 public struct HEXDATA {
        [MarshalAs(UnmanagedType.U2)]
        public UInt16 usLength;
        [MarshalAs(UnmanagedType.?????)]
        public byte[] lpbData;
    } ;

Thanks

Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
Hossein
  • 3
  • 2
  • 1
    Possible duplicate of [How do I marshal a struct that contains a variable-sized array to C#?](https://stackoverflow.com/questions/5902103/how-do-i-marshal-a-struct-that-contains-a-variable-sized-array-to-c) –  Nov 13 '17 at 18:15
  • 1
    A struct like this has a nasty memory management problem, it is not obvious who is responsible for releasing the memory that the LPBYTE points to. So you cannot declare it byte[] and must use `IntPtr` instead. Marshal::Copy() to copy it, hopefully usLength tells you many bytes. But you'll have to think about what need to happen to clean up properly. – Hans Passant Nov 13 '17 at 18:22
  • By the way, this structure is misnamed. There is no hex here. Hex is a base 16 representation of numbers. What you have here is simple an array of bytes. There is no representation at all. – David Heffernan Nov 14 '17 at 08:02

2 Answers2

1

It should be

[StructLayout(LayoutKind.Sequential)]
public struct HEXDATA
{
   public ushort usLength;
   public IntPtr lpbData;
};

pack is in general not needed (in general only if pack is specified on the C/C++ size). There is no string here, so no CharSet is needed either.

Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
0

LPBYTE is a pointer to a byte array. Since its a pointer to an array, you would use the LPArray type.

https://learn.microsoft.com/en-us/dotnet/framework/interop/default-marshaling-for-arrays