Marshalling struct with embedded pointer from C# to unmanaged driver

后端 未结 3 566
闹比i
闹比i 2021-01-20 17:08

I\'m trying to interface C# (.NET Compact Framework 3.5) with a Windows CE 6 R2 stream driver using P/Invoked DeviceIoControl() calls . For one of the IOCTL codes, the driv

相关标签:
3条回答
  • 2021-01-20 17:32

    You might have to specify the size of the byte[] (replace 64 with the actual size)

    [StructLayout(LayoutKind.Sequential, Pack=1)]
    public struct IoctlWriteRegsIn
    {    
       public uint Address; 
       [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] 
       public byte[] Buffer; 
       public uint Size;
    }
    

    Then you should be able to set the size like this:

    IoctlWriteRegsIn io_struct = new IoctlWriteRegsIn();
    io_struct.Address = 5;
    io_struct.Buffer = new byte[1] { 0xBE };
    // size of buffer, not struct
    io_struct.Size = 1;//Marshal.SizeOf(io_struct); 
    

    I would change the P/Invoke call to this:

    [DllImport("coredll.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    static extern bool DeviceIoControl(IntPtr hDevice,  
       UInt32 dwIoControlCode,
       ref IoctlWriteRegsIn lpInBuffer, 
       UInt32 nInBufferSize,
       IntPtr lpOutBuffer,
       UInt32 nOutBufferSize,
       ref UInt32 lpBytesReturned,
       IntPtr lpOverlapped);
    

    and call it using this:

    uint num_bytes = (uint)Marshal.SizeOf(writeInBuffer);
    bool writeSuccess = DeviceIoControl(driverHandle, IoctlTwlWriteRegs, ref writeInBuffer, num_bytes, IntPtr.Zero, 0, ref numBytesReturned, IntPtr.Zero);
    
    0 讨论(0)
  • 2021-01-20 17:33

    When marshaling a struct which has an inline pointer, you need to define the value as an IntPtr and not an array

    [StructLayout(LayoutKind.Sequential)]
    public struct IoctlWriteRegsIn
    {
        public uint Address;
        public IntPtr Buffer;
        public uint Size;
    }
    
    0 讨论(0)
  • 2021-01-20 17:33

    Give it a shot by replacing the byte[] array with an IntPtr..

    0 讨论(0)
提交回复
热议问题