C# Developers' Journal (original) (raw)

Marshaling a union with a pointer I am using Mono on Linux, and want to marshal the following unmanaged structure to a native one:


int 	type
union {
   guint32   u
   gint32   i
   gboolean   b
   gdouble   d
   gchar *   s
} 	value

According to Mono's excellent page on native-library interop, the way to deal with unions is to use StructLayoutAttribute with LayoutKind.Explicit and specify a FieldOffsetAttribute that is the same for all union members. So you might do something similar to this:


[StructLayout(LayoutKind.Explicit)]
public struct Rpc {
 [FieldOffset(0)] public int type;
 [FieldOffset(4)] public uint value_u;
 [FieldOffset(4)] public int value_i;
 [FieldOffset(4)] public bool value_b;
 [FieldOffset(4)] public double value_d;
 [FieldOffset(4)] public string value_s;
}

The problem however is this, the Mono runtime crashes when this code is run, complaining that: "you cannot have a reference field that is the same offset as another field" in an [ExplicitLayout] structure. I assume this is referring to the last member of the union which is a pointer. Thing is, I'm not sure how else to do this.

I thought about just having a "public object value;" member of the structure, and then casting this as appropriate in managed code, but the runtime apparently cannot marshal to a vanilla object this way.

Thoughts?