tags:

views:

145

answers:

4

I have a structure

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct SERVER_USB_DEVICE
{
    USB_HWID usbHWID;
    byte status;
    bool bExcludeDevice;
    bool bSharedManually;
    ulong ulDeviceId;
    ulong ulClientAddr;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
    string usbDeviceDescr;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
    string locationInfo;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
    string nickName;
}

When I pass it in a win32 DLL function as below:

[DllImport ("abc.dll", EntryPoint="EnumDevices", CharSet=CharSet.Ansi)]
public static extern bool EnumDevices(IntPtr lpUsbDevices,
                                      ref  ulong pulBufferSize, 
                                      IntPtr lpES);

I get some missing text in the string members of the structure.

Suppose SERVER_USB_DEVICE.usbDeviceDescr contains value "Mass Storage Device" which is wrong it should contain value "USB Mass Storage Device"

What is wrong in the code?

A: 

Try with ByValTStr instead of ByValArray

Thomas Levesque
well i changed to ByValTStr but no effect
Abdul Khaliq
OK... could you post the C signature for the EnumDevices function ?
Thomas Levesque
BOOL EnumDevices( PFT_SERVER_USB_DEVICE lpUsbDevices, PULONG pulBufferSize, PFT_ERROR_STATE lpES );
Abdul Khaliq
You could try to specify an array of SERVER_USB_DEVICE rather than an IntPtr in the C# declaration
Thomas Levesque
A: 

Have you verified that the fields in the structure that are located before usbDeviceDescr (status, bExcludeDevice, bSharedManually, ulDeviceId, and ulClientAddr) get their correct values? Could it be that it is the marshalling of the USB_HWID structure that is wrong, so that the offsets are off by 4 bytes for the rest of the structure?

Fredrik Mörk
A: 

You can look at the structure in a byte array to make sure you have everything aligned properly. Try this:

int size = Marshal.SizeOf(typeof(SERVER_USB_DEVICE));
byte[] buffer1 = new byte[size];
SERVER_USB_DEVICE[] buffer2 = new SERVER_USB_DEVICE[1];
// put instance of SERVER_USB_DEVICE into buffer2
Buffer.BlockCopy(buffer2, 0, buffer1, 0, size);
Bryan
+1  A: 

Actually i was making a small mistake here ulong is 8 bytes in c# where as it is 4 bytes in c++ (as we all know). converting ulong to uint solved the problem.

Abdul Khaliq