Hi Javier,

Ok, I understand :)

Another question, how should I get access to the nested structures?,
some unmanaged functions need access to the structures..

first declare a dummy field for the struct begining with
the first offset of the union:

   [StructLayout (LayoutKind.Explicit)]
   public struct event_struct {
                [FieldOffset(0)] public IntPtr next;
                [FieldOffset(4)] public int type;
                [FieldOffset(8)] public int unionStart;
                ....

With Marshal.OffsetOf (typeof (event_struct), "unionStart")
you get the offset of the start of the union within the struct.

Next you have to change all p/invoke declarations to take
an IntPtr as an argument instead of the struct name:

from

        static extern int foo (ev_levels input, ev_levels output);

to
        static extern int foo (IntPtr input, IntPtr output);

Before you call such a p/invoke method you have to pin the
struct, because the default marshal cannot help you anymore:

int managed_foo (event_struct input , event_struct output)
{
  GCHandle h1 = GCHandle.Alloc (input, GCHandleType.Pinned);
  GCHandle h2 = GCHandle.Alloc (output, GCHandleType.Pinned);
  try {
    // this is actually a constant, you may factor the call out.
    IntPtr offset = Marshal.OffsetOf (typeof (event_struct),
                                      "unionStart");
    return levels_callback (h1.AddrOfPinnedObject () + offset,
                            h2.AddrOfPinnedObject () + offset);
  }
  finally {
    h1.Free ();
    h2.Free ();
  }
}


onother way (which I never used with Mono) using "unsafe" code
and pointers:

unsafe int managed_foo (event_struct input , event_struct output)
{
  fixed (int* i = &input.ev.input)
  fixed (int* o = &output.ev.output) {
    return levels_callback (new IntPtr(i), new IntPtr(o));
  }
}


> ---------------------------------------
>
> can I create something like this ?
>
> ---------------------------------------
> public struct new_event_struct : event_struct {
>    public ev_levels levels {
>            get { return ....; }
>    }
> }
> ---------------------------------------

I don't know. You must use classes for inheritance. I don't know
how classes and inheritance cope with FieldOffset and StructLayout.

Rob

_______________________________________________
Mono-list maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-list

Reply via email to