Reputation: 1296
I have unmanaged structure:
typedef struct
{
char a[48];
BYTE b;
BYTE c;
BYTE d;
BYTE e;
BYTE f;
BYTE x;
char y[32];
char z[128][32];
}SOMELIKE_STRUCT
I tried to marshal it as it was written in another threads in StackOverflow:
[StructLayout(LayoutKind.Explicit, Pack = 1)]
public struct SOMELIKE_STRUCT
{
[FieldOffset(0)]
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 48)]
public byte[] a;
[FieldOffset(48)]
public byte b;
[FieldOffset(49)]
public byte c;
[FieldOffset(50)]
public byte d;
[FieldOffset(51)]
public byte e;
[FieldOffset(52)]
public byte f;
[FieldOffset(53)]
public byte x;
[FieldOffset(54)]
[MarshalAs(UnmanagedType.ByValArray, ArraySubType=UnmanagedType.U1, SizeConst = 32)]
public byte[] y;
[FieldOffset(86)]
[MarshalAs(UnmanagedType.ByValArray, ArraySubType=UnmanagedType.Struct, SizeConst = 128)]
public STRUCT[] z;
}
[StructLayout(LayoutKind.Explicit, Pack = 1)]
public struct STRUCT
{
[FieldOffset(0)]
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 32)]
public byte[] name;
}
I have exception:
System.TypeLoadException was unhandled Additional information: Could not load type 'SOMELIKE_STRUCT' from assembly 'ConsoleApplication2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset '54' that is incorrectly aligned or overlapped by a non-object field.
Exception shows when I create this struct with new:
SOMELIKE_STRUCT l = new SOMELIKE_STRUCT();
Exception shows when I will create class (when step into constructor) using that structure (before create instance of that structure)
Upvotes: 3
Views: 2072
Reputation: 1296
Structures and tables contained in struct have to be placed at address being multiple of word (4/8 bytes for x86/x64).
Upvotes: 1
Reputation: 5515
Can't quite figure out what's going on here as your definitions seems correct.
Changing the layout to sequential and removing the manual field offsets seems to work:
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
public struct SOMELIKE_STRUCT
{
[MarshalAs( UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 48 )]
public byte[] a;
public byte b;
public byte c;
public byte d;
public byte e;
public byte f;
public byte x;
[MarshalAs( UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 32 )]
public byte[] y;
[MarshalAs( UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 128 )]
public STRUCT[] z;
}
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
public struct STRUCT
{
[MarshalAs( UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 32 )]
public byte[] name;
}
Checking the size with Marshal.SizeOf
gives 4182 bytes, and checking the resulting layout with Marshal.OffsetOf
gives the same offsets as in your original code. I'm sure someone else here can elaborate on why this is happening.
Upvotes: 3