【问题标题】:marshal c struct to c#将 c 结构编组为 c#
【发布时间】:2013-06-29 10:58:58
【问题描述】:

请问有没有机构可以在 c# 中编组这部分 c/c++ 代码?

typedef struct
{
    BYTE    bCommandCode;
    BYTE    bParameterCode;

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

非常感谢

【问题讨论】:

  • 到目前为止你尝试了什么?

标签: c# struct marshalling typedef


【解决方案1】:

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

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

【讨论】:

  • 然后只需将 lpBody 更改为 byte[] 就可以了。一定要指定字节数组的长度,否则东西可能会变南。
  • struct Data {} 是一个很奇怪的声明。在问题中“数据”是内部结构的名称
  • 我无法从他发布的代码中推导出 Data 结构中应该包含的内容,您当然应该向其中添加成员并使用 [MarshalAs] 属性正确编组它们并指定 @ 987654329@ 如果需要。
【解决方案2】:
//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();

【讨论】:

    猜你喜欢
    • 2014-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-17
    • 2022-11-22
    • 1970-01-01
    相关资源
    最近更新 更多