Marshall Struct包含带数组的联合

时间:2013-12-06 10:15:13

标签: c# struct marshalling unions

我正在尝试在c#

中编组以下非托管c结构
typedef struct {
PNIO_ADDR_TYPE  AddrType; /* Enum: size:32bits */
PNIO_IO_TYPE IODataType; /* Enum: size:32bits */
union {
    PNIO_UINT32 Addr;  /* logical address */

    PNIO_UINT32  Reserved [5];
} u;
} ATTR_PACKED PNIO_ADDR;

使用托管结构时出现以下错误:

错误:PresentationCore.dll中出现未处理的“System.TypeLoadException”类型异常

附加信息:无法从程序集“xx.xx.xx,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null”加载类型“PNIO_ADDR”,因为它包含偏移量为8的对象字段,该字段未正确对齐或由非对象字段重叠。

这是我的托管结构:

// size:28bytes
[StructLayout(LayoutKind.Explicit, Pack = 1)]
public struct PNIO_ADDR
{
    [FieldOffset(0)]
    public PNIO_ADDR_TYPE AddrType;

    [FieldOffset(4)]
    public PNIO_IO_TYPE IODataType;

    // container, size:20bytes
    [FieldOffset(8)]
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
    public uint[] Reserved;

    [FieldOffset(8)]
    [MarshalAs(UnmanagedType.U4)]
    public uint Addr;
}     

我的编组错误还是与包属性和处理器架构有关。 Rightnow我正在AnyCpu配置中编译程序集。

1 个答案:

答案 0 :(得分:1)

您可以使用修复关键字进行修复。但在这种情况下,您还需要检查项目属性中的“允许不安全的代码”。所以你的结构将是:

[StructLayout(LayoutKind.Explicit, Pack = 1)]
public unsafe struct PNIO_ADDR
{
    [FieldOffset(0)]
    public PNIO_IO_TYPE AddrType;

    [FieldOffset(4)]
    public PNIO_IO_TYPE IODataType;

    // container, size:20bytes
    [FieldOffset(8)]
    //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
    public fixed uint Reserved[5];

    [FieldOffset(8)]
    [MarshalAs(UnmanagedType.U4)]
    public uint Addr;
}