Consider the case where I need to ensure a class/struct is mapped to memory in a very specific way, probably due to the need to match an external protocol:
[StructLayout(LayoutKind.Sequential, Pack=1)]
public class SYSTEM_INFO
{
public ulong OemId;
public ulong PageSize;
public ulong ActiveProcessorMask;
public ulong NumberOfProcessors;
public ulong ProcessorType;
}
Then I thought about doing an 'overlay' (is this a proper term?) so I can directly access the memory:
[StructLayout(LayoutKind.Explicit)]
public class SYSTEM_INFO
{
[FieldOffset(0)] public byte[] Buffer = new byte[40]; //overlays all the bytes, like a C union
[FieldOffset(0)] public ulong OemId;
[FieldOffset(8)] public ulong PageSize;
[FieldOffset(16)] public ulong ActiveProcessorMask;
[FieldOffset(24)] public ulong NumberOfProcessors;
[FieldOffset(32)] public ulong ProcessorType;
}
But this gets time-consuming and error-prone (if something changes I could easily mess up updating all the FieldOffset
values) - and has been pointed out is actually not valid for reasons I do not fully understand:
Unhandled exception. System.TypeLoadException: Could not load type 'SYSTEM_INFO2' from assembly 'a2bbzf3y.exe, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 0 that is incorrectly aligned or overlapped by a non-object field. Command terminated by signal 6
Is it possible to do a combination of both approaches, where Buffer
overlays the members, but all members except Buffer
are automatically, sequentially aligned without padding? I cannot make out from the docs if this is allowed or not, and I can force some member offsets only with others automatically decided.