문제

I'm trying to marshall the following unmanaged c struct in 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;

I'm getting the following error when using the managed struct:

Error: An unhandled exception of type 'System.TypeLoadException' occurred in PresentationCore.dll

Additional information: Could not load type 'PNIO_ADDR' from assembly 'xx.xx.xx, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 8 that is incorrectly aligned or overlapped by a non-object field.

This is my managed struct:

// 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;
}     

Is my marshalling wrong or is it something to do with the pack attribute and processor architecture. Rightnow I'm compiling the assembly in AnyCpu configuration.

도움이 되었습니까?

해결책

You may fix it by using fixed keyword. But in this case you also need to check "Allow unsafe code" in the project properties. So your struct will be:

[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;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top