1

In C++ I have a struct:-

typedef struct
{
    unsigned char ucSpeed;
    unsigned long ulLength;
    unsigned char ucBulkInPipe;
    unsigned char ucBulkOutPipe;
    unsigned char ucInterruptPipe;
}USB_DEVICE_INFO, *PUSB_DEVICE_INFO;

In header I have:-

_API BOOL _InitialiseDevice(PUSB_DEVICE_INFO pDevInfo);

in CPP file I have a function

_API BOOL _InitialiseDevice(PUSB_DEVICE_INFO pDevInfo)

In C# I have struct:-

[StructLayout(LayoutKind.Sequential , Pack = 8)]
public struct USB_DEVICE_INFO
        {
            public byte ucSpeed ;
            [MarshalAs(UnmanagedType.U8)]
            public long ulLength;
            public byte ucBulkInPipe;
            public byte ucBulkOutPipe;
            public byte ucInterruptPipe;
        }

And calling it like this:-

[[DllImport(@"32.dll")]
public static extern bool _InitialiseDevice(out PUSB_DEVICE_INFO pDevInfo);
  
if (_InitialiseDevice(out m_sDeviceInfo) == false)
   

There are no errors except that the struct in C# isn't filled as I expected. The struct is filled in c++ like:-

ucSpeed = 1
ulLength = 1
ucBulkInPipe = 130
ucBulkOutPipe = 2
ucInterruptPipe = 0

But in C# it looks like this:-

ucBulkInPipe = 0
ucBulkOutPipe = 0
ucInterruptPipe = 0
ucSpeed = 1
ulLength = 642

I'm assuming I'm not marshalling it correctly but not sure how to correct it

  • 1
    Remove the `Pack = 8` and the `[MarshalAs(UnmanagedType.U8)]`, and replace the `long` with `int`. Also verify that your `_API` expands to something like `__stdcall`, otherwise fix the calling convention in the `DllImport` too. – GSerg Apr 12 '23 at 11:40
  • FYI, `_API` would be reserved for compiler use in C++ – ChrisMM Apr 12 '23 at 11:49
  • Your spot on GSerg. I removed the Pack = 8 and [MarshalAs(UnmanagedType.U8)]. Changed the Long to an int and it work – Nick Pitman Apr 12 '23 at 11:54
  • You might also be interested in writing a C++/cli wrapper which will give you more control wrt lifetime of objects. https://www.codeproject.com/Articles/19354/Quick-C-CLI-Learn-C-CLI-in-less-than-10-minutes. In the C++/cli layer you can define a managed structure and copy your C++ structure into that. (Avoids issues with pinning to keep the garbage collector from moving things around etc) – Pepijn Kramer Apr 12 '23 at 12:49

0 Answers0