Youll need a 64bit machine if you want to see the actuall exception. I’ve created some dummy classes that repro’s the problem.
[StructLayout(LayoutKind.Sequential, Pack = 1)] public class InnerType { char make; char model; UInt16 series; } [StructLayout(LayoutKind.Explicit)] public class OutterType { [FieldOffset(0)] char blah; [FieldOffset(1)] char blah2; [FieldOffset(2)] UInt16 blah3; [FieldOffset(4)] InnerType details; } class Program { static void Main(string[] args) { var t = new OutterType(); Console.ReadLine(); } }
If I run this on the 64 clr, I receive a type load exception,
System.TypeLoadException was unhandled Message='Could not load type 'Sample.OutterType' from assembly 'Sample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 4 that is incorrectly aligned or overlapped by a non-object field.'
If i force the target cpu to 32, it works fine.
Also, if i change InnerType from a class to a struct it also works. Can someone explain whats going on or what I am doing wrong ?
thanks
The part about overlapping types is misleading here. The problem is that in .Net reference types must always be aligned on pointer size boundaries. Your union works in x86 since the field offset is 4 bytes which is the pointer size for a 32 bit system but fails on x64 since there it must be offset a multiple of 8. The same thing would happen if you set the offset to 3 or 5 on the x86 platform.
EDIT: For the doubters – I couldn’t find a ready reference on the internet but check out Expert .NET 2.0 IL Assembler By Serge Lidin page 175.