I came across odd marshaling union scenarios that contain arrays in C # /. NET Consider the following program:
namespace Marshal { class Program { [StructLayout(LayoutKind.Sequential, Pack = 1)] struct InnerType { byte Foo;
If you run this program, you will get the following exception:
Could not load type 'UnionType' from assembly 'Marshal, Version=1.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.
Now, if you uncomment two missing lines, the program will work fine. I wonder why this is so. Why does adding an extra array to InnerType fix the problem? By the way, no matter what size you make in the array. Without an array, UnionMember1 and UnionMember2 must match each other in size. With the array, their sizes do not match, but exceptions are not thrown.
Change InnerType update the following as causes an exception (InnerType at this time):
[StructLayout(LayoutKind.Explicit, Pack = 1)] struct InnerType { [FieldOffset(0)] byte Foo; [FieldOffset(1)] [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)] byte[] Bar; }
It seems to me that this should be equivalent to the source code (with LayoutKind.Sequential ), where byte[] Bar uncommented.
I donβt think the problem here has anything to do with word boundaries β I use Pack = 1. Rather, I think this is the second part of the exception, "... it contains the field of the object at offset 0, which ... is overlapped by the field different from the object. " byte [] is a reference type, while the byte itself is a value type. I see that "byte Foo" will override "byte [] UnionMember2". However, this still does not explain why uncommenting the "byte [] bar" in my source code throws an exception.