Unions in C#
Usage of unions in the native world is pretty common. However, the same is not true for the .NET world. However, while using interop sometimes you need to fiddle around this these.
In C# you go about defining unions using the Explicit layout supported by struct as follows.
[StructLayout(LayoutKind.Explicit)]
public struct MyUnion
{
[FieldOffset(0)]
public UInt16 myInt;
[FieldOffset(0)]
public Byte byte1;
[FieldOffset(1)]
public Byte byte2;
}
Here the StructLayout(LayoutKind.Explicit)
is used to indicate that the stuct definition contains the layout explicitely. FieldOffset(offset)
is used to specify the offset of the struct field from the start of the struct.
In the example above the layout of the struct is somewhat as follows
<<========== MyUnion (16 bits)========>>
+--------------------------------------+
| myInt (16-bit) |
+------------------+-------------------+
| byte1 (8 bit) | byte2 (8 bit) |
+------------------+-------------------+
byte1
and byte2
share storage with myInt
. The following code prints them out and highlight the fact that the system I used (Intel processor based) is little-endian.
MyUnion union;
union.byte1 = 0; // needed to make the compiler happy
union.byte2 = 0;
union.myInt = 0xAABB;
Console.WriteLine("{0:X}", union.byte1);
Console.WriteLine("{0:X}", union.byte2);
// output is
BB
AA
Since the system is little-endian the LSB (0xBB) goes to the first byte and the MSB (0xAA)goes to the second.
<rant>
All this is very cool. The only thing that made me a bit unhappy is that the definite assignment verifier couldn't figure out that I needn't do the byte1, byte2 assignment to access them.
</rant>
Comments
Anonymous
September 24, 2007
PingBack from http://www.artofbam.com/wordpress/?p=2678Anonymous
September 26, 2007
http://www.hanselman.com/blog/UnionsOrAnEquivalentInCSairamasTipOfTheDay.aspx