将c结构封送为c#

本文关键字:结构 | 更新日期: 2023-09-27 18:20:34

是否有任何主体可以封送c#中的这部分c/c++代码?

typedef struct
{
    BYTE    bCommandCode;
    BYTE    bParameterCode;
    struct
    {
        DWORD   dwSize;
        LPBYTE  lpbBody;
    }
    Data;
}
COMMAND, *LPCOMMAND;

非常感谢

将c结构封送为c#

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

    [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的情况下编译上述代码。

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