[Mono-list] Marshalling union crashes

Jef Driesen jefdriesen at hotmail.com
Fri Jun 18 07:27:25 EDT 2010


Hi,

I would like to marshall a C struct, that looks like this:

typedef union parser_sample_value_t {
     unsigned int time;
     double depth;
     struct {
         unsigned int tank;
         double value;
     } pressure;
     struct {
         unsigned int type;
         unsigned int size;
         const void *data;
     } vendor;
} parser_sample_value_t;

I have defined these C# structures:

[StructLayout(LayoutKind.Sequential)]
public struct sample_pressure_t {
     public uint tank;
     public double value;
};

[StructLayout(LayoutKind.Sequential)]
public struct sample_vendor_t {
     public uint type;
     public uint size;
     public IntPtr data;
};

[StructLayout(LayoutKind.Explicit)]
public struct parser_sample_value_t {
     [FieldOffset(0)] public uint time;
     [FieldOffset(0)] public double depth;
     [FieldOffset(0)] public sample_pressure_t pressure;
     [FieldOffset(0)] public sample_vendor_t vendor;
};

This seems to work fine with MS .NET, but crashes under mono with the error:

"Got a SIGABRT while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries
used by your application."

I'm sure there is no bug in the native code, because it works fine from 
other native applications. When I remove the two nested structs from the 
union it works again, so I suspect the error is there somewhere. It 
doesn't matter which struct is actually present in the union. As soon as 
there is one, it crashes.

Note that in my case, the struct needs to be marshalled from native code 
to managed code, because it's used in a callback function:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void sample_callback_t (parser_sample_type_t type, 
parser_sample_value_t value, IntPtr userdata);

[DllImport("libdivecomputer-0.dll")]
static extern parser_status_t parser_samples_foreach (parser_t parser, 
sample_callback_t callback, IntPtr userdata);

public void sample_cb (parser_sample_type_t type, parser_sample_value_t 
value, IntPtr userdata)
{
    /* some code here */
}

public static void Main(string[] args)
{
    /* some code here */

    parser_samples_foreach (parser, sample_cb, IntPtr.Zero);

    /* some code here */
}

Any ideas?

Jef


More information about the Mono-list mailing list