0

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.

jero2rome
  • 1,548
  • 1
  • 21
  • 39

1 Answers1

1

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;
}
Deffiss
  • 1,136
  • 7
  • 12
  • I used fixed keyword as u suggested and enabled 'Allow unsafe code' in project properties, but intellisense tells me 'cannot use unsafe construct in safe context' – jero2rome Dec 06 '13 at 11:34
  • Pay attention that I declare sruct like **public unsafe struct PNIO_ADDR{..}**. I think you missed **unsafe** keyword in struct declaration. – Deffiss Dec 06 '13 at 11:37
  • Thanks Deffiss. unsafe struct did the trick. That works like charm. – jero2rome Dec 06 '13 at 11:45