marshal c struct to c#

时间:2013-06-29 10:58:58

标签: c# struct marshalling typedef

是否有任何机构可以在c#中编组这部分c / c ++代码?

typedef struct
{
    BYTE    bCommandCode;
    BYTE    bParameterCode;

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

非常感谢

2 个答案:

答案 0 :(得分:0)

首先,将上述结构声明为托管结构 - 类似于:

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

        SomeOtherStruct otherStruct;

        Data Data;
    }

    struct SomeOtherStruct
    {
        uint dwSize;
        byte lpBody;
    }

    struct Data
    {
    }

虽然您可能必须在此处使用MarshalAs属性,以确保它实际上将它们编组为正确的类型。例如,如果你想从内存中读取这个结构,你可以这样做:

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

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

我假设您想从内存中读取结构并将其编组为托管结构,因为否则您根本不需要Marshal。另外,请确保在启用/unsafe的情况下编译上述代码。

答案 1 :(得分:0)

//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();