Interop and Unions

A frequent question I see pop up on news groups is how to create Unions in managed code for interop with P/Invoke.  .NET does not directly support unions but you can use some Marshal magic to get them working.  Take the following C union. 

union Foo

{

   int a;

   float b;

}

Really what this translates to in the native world is a data structure that is 4 bytes long (the key to Marshalling is never forgetting that you are just dealing with bytes).  To simulate this in .NET you could probably get away with creating a structure that is 4 bytes long and passing that in.  You'd loose the easy type switch that you get with unions but it would most likely work.  To get the nice type switch you do the following.

[StructLayout(LayoutKind.Explicit)]

public struct ManagedFoo

{

   [FieldOffset(0)] int a;

   [FieldOffset(0)] float b;

}

The attributes here will cause the fields to both be aligned at the very begining of the structure.  This gives you the benefits of a Union in C# and the compatibility to Marshall with P/Invoke. 

There is one catch with this technique.  You cannot mix value and reference types in a Managed union.  If you do you will get a nasty type load exception at runtime.  The best work around in that case is to use an IntPtr in place of the reference types and do some additional Marshalling on that field.