[Mono-dev] Issues with StructureToPtr- and PtrToStructure-wrapper building

Martin Däumler mdae at cs.tu-chemnitz.de
Tue Feb 8 04:51:06 EST 2011


I have some questions about how StructureToPtr- and
PtrToStructure-wrappers are built within Mono.

The marshalling wrappers are generated by
'mono_marshal_get_ptr_to_struct (MonoClass *)' and
'mono_marshal_get_struct_to_ptr (MonoClass *)' respectively.
These functions are called by the Full-AOT code
(of Mono 2.8.2 and 2.6.1) and they are also used to
generate wrappers at runtime in JIT-mode. I try to
implement a pre-compilation routine that runs right
before 'mono_jit_exec()'. This routine should
generate the StrcutureToPtr- and PtrToStructure-wrappers
for all classes and structs that can be marshalled
(and compile it in advance). I use the code of
'add_wrappers()' of the Full-AOT system as code base.
However, the Full-AOT code is very restricting.
The following costum class is skipped by the Full-AOT
code but a wrapper can be generated at runtime
and also by my pre-compilation routine:

     [StructLayout(LayoutKind.Sequential, Pack=4)]
     public sealed class ProcessImage
         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
          public  int[] control;

         public byte bytedata;

         public Int16 worddata;

         public int intdata;

         public float floatdata;

         public bool booldata;

When trying to adopt the pre-compilation routine to the mscorlib,
some classes cause a SIGABRT. For example, 'System.MonoEnumInfo',
'System.Configuration.Assemblies.AssemblyHash' or 'ProcessMessageRes'
do not work. The stacktrace is always as follows:

** ERROR **: Structure field of type Byte[] can't be marshalled as LPArray


Thread 1 (Thread 0xb78c56e0 (LWP 31210)):
#0  0x00dcd422 in __kernel_vsyscall ()
#1  0x0011cf5b in read () from /lib/tls/i686/cmov/libpthread.so.0
#2  0x0810b8be in mono_handle_native_sigsegv (signal=6, ctx=0xbfa0353c) 
at mini-exceptions.c:1818
#3  0x0815e383 in sigabrt_signal_handler (_dummy=6, info=0xbfa034bc, 
context=0xbfa0353c) at mini-posix.c:154
#4  <signal handler called>
#5  0x00dcd422 in __kernel_vsyscall ()
#6  0x001d4651 in raise () from /lib/tls/i686/cmov/libc.so.6
#7  0x001d7a82 in abort () from /lib/tls/i686/cmov/libc.so.6
#8  0x00a24026 in g_logv () from /lib/libglib-2.0.so.0
#9  0x00a24056 in g_log () from /lib/libglib-2.0.so.0
#10 0x081f08a5 in emit_ptr_to_object_conv (mb=0xb6d8cb58, 
type=0x8797154, conv=MONO_MARSHAL_CONV_ARRAY_LPARRAY, mspec=0x0) at 
#11 0x081f1f4f in emit_struct_conv (mb=0xb6d8cb58, 
klass="ProcessMessageRes", to_object=1) at marshal.c:1950
#12 0x082044ff in mono_marshal_get_ptr_to_struct 
(klass="ProcessMessageRes") at marshal.c:9076

So, my question is: Which classes and structs allow the generation
of StructureToPtr- and PtrToStructure-wrappers at all and how to
determine these?

According to the MSDN [1,2], one can adopt the 'Marshal.PtrToStructure'
and 'Marshal.StructureToPtr' method to a "formatted class or structure".
A formatted class is a class with layout information [3], as far as I
understood this. However, the classes that are mentioned above and that
do not work have the 'SequentialLayout'-attribute set. So, why it is
not possible to generate the marshalling wrappers?

I hope, anyone can give me a hint.

With kind regards,
Martin Däumler

[1] http://msdn.microsoft.com/en-us/library/4ca6d5z7.aspx

More information about the Mono-devel-list mailing list