[Mono-list] Question about Mono to native function calling

Bruce Wilkie bruce at bwilkie.com
Mon Nov 7 11:47:12 EST 2005


Hello Mono lists - I'm emailing both lists in hopes
someone has a tip or two.

some background - I'm in a situation where i can't
generate code at runtime.  so I'm trying to use the
interp package, by embedding it into my application. 
my current test case is pretty simple:

           
System.Diagnostics.Trace.WriteLine("Hello");

that one line is sooo deceptively simple...

one challenge that I have to solve is that even the
interp package wants to generate code at runtime - for
each native function called (internal calls and
PInvoke) a little bit of ASM gets generated to allow
variables on the managed interp stack to flow to the
native function, as well as a return value. 
currently, based on the sig of the function being
called, I'm looking up a hand-written function to
replace the little bit of ASM that would normally be
generated.  This is (for the most part) working great,
and I get 41 native calls in before things go wrong. 
:(

like I said, that one line is deceptively simple...

So, I'm hoping the lists have an idea about how those
hand-written functions should look?  for example, take
the native function GetDataTablePointers.  it returns
void, and it's sig is:

System.Char.GetDataTablePointers(byte*&,byte*&,double*&,uint16*&,uint16*&,uint16*&,uint16*&)

my first thought was to do this:

    void
Thunk_void_refintptr_refintptr_refintptr_refintptr_refintptr_refintptr_refintptr(MonoFunc
callMe, void *pRetval, void *this_obj, stackval
*arguments)
    {
        typedef void (*Func)(void**, void**, void**,
void**, void**, void**, void**);
        (*(Func)(callMe))((void**)arguments[0].data.p,
(void**)arguments[1].data.p,
(void**)arguments[2].data.p,
(void**)arguments[3].data.p,
(void**)arguments[4].data.p,
(void**)arguments[5].data.p,
(void**)arguments[6].data.p);
    }


and the native function it calls is:

static void
ves_icall_System_Char_GetDataTablePointers (guint8
const **category_data,
                        guint8 const **numeric_data,
                        gdouble const
**numeric_data_values,
                        guint16 const
**to_lower_data_low,
                        guint16 const
**to_lower_data_high,
                        guint16 const
**to_upper_data_low,
                        guint16 const
**to_upper_data_high)
.
.
.

another example, InternalTrim.  It returns a
MonoString*, and it's sig is:

System.String.InternalTrim(char[],int)

my thought was to do this:

    void Thunk_intptr_thisobj_intptr_int(MonoFunc
callMe, void *pRetval, void *this_obj, stackval
*arguments)
    {
        stackval* retval = (stackval*)pRetval;

        typedef void* (*Func)(void*, void*, int);
        retval->data.p = (*(Func)(callMe))(this_obj,
arguments[0].data.p, arguments[1].data.i);
    }


and the native function it calls is:

MonoString * 
ves_icall_System_String_InternalTrim (MonoString *me,
MonoArray *chars, gint32 typ)
.
.
.

again - most everything works.  I'm prototyping all
this on the PC first.  When I enable original
mono_arch_create_trampoline function (it generates
code at runtime), everything is fine - I see "Hello". 
when I enable my version of
mono_arch_create_trampoline, that looks up sigs and
gives back hand-written thunks, I end up dying in
ves_icall_System_String_InternalJoin, because the
first arg being passed is junk.  :(  this is all with
the interp engine, so i can step almost everything if
someone has a pointer what to look for.  please feel
free to offlist email me for more details if you think
you can help but have more questions.

thanks in advance lists!
bruce




More information about the Mono-list mailing list