marshal c struct to c#

2019-06-12 10:58发布

Does any body can marshal this part of c/c++ code in c# please?

typedef struct
{
    BYTE    bCommandCode;
    BYTE    bParameterCode;

    struct
    {
        DWORD   dwSize;
        LPBYTE  lpbBody;
    }
    Data;
}
COMMAND, *LPCOMMAND;

thanks a lot

2条回答
劳资没心,怎么记你
2楼-- · 2019-06-12 11:30
//01. Declare 'Command' structure
public struct Command
{
    public byte CommandCode;
    public byte ParameterCode;
    public struct Data
    {
        public uint Size;
        public IntPtr Body;
    }
    public Data SendData;
}    

//02. Create & assign an instance of 'Command' structure 
//Create body array
byte[] body = { 0x33, 0x32, 0x34, 0x31, 0x30 };

//Get IntPtr from byte[] (Reference: http://stackoverflow.com/questions/537573/how-to-get-intptr-from-byte-in-c-sharp)
GCHandle pinnedArray = GCHandle.Alloc(body, GCHandleType.Pinned);
IntPtr pointer = pinnedArray.AddrOfPinnedObject();

//Create command instance
var command = new CardReaderLib.Command
                  {
                      CommandCode = 0x30,
                      ParameterCode = 0x30,
                      SendData = {
                          Size = (uint) body.Length, 
                          Body = pointer
                      }
                  };

//do your stuff

if (pinnedArray.IsAllocated)
    pinnedArray.Free();
查看更多
乱世女痞
3楼-- · 2019-06-12 11:43

First off, declare the above struct as a managed struct - something like:

    [StructLayout(LayoutKind.Sequential)]
    struct SomeStruct
    {
        byte bCommandCode;
        byte bParameterCode;

        SomeOtherStruct otherStruct;

        Data Data;
    }

    struct SomeOtherStruct
    {
        uint dwSize;
        byte lpBody;
    }

    struct Data
    {
    }

Though you may have to use the MarshalAs attribute here and there to ensure it's actually marshalling them as their proper types. If you want to then read this struct from memory for example, you could do something like:

        var bytes = ReadBytes(address, Marshal.SizeOf(typeof(SomeStruct)), isRelative);

        fixed (byte* b = bytes)
            return (T) Marshal.PtrToStructure(new IntPtr(b), typeof (SomeStruct));

I am assuming you want to read your struct from memory and marshal it into a managed struct, because otherwise you wouldn't even need the Marshal at all. Also, make sure to compile the above code with /unsafe enabled.

查看更多
登录 后发表回答