[Mono-list] [embedding] "moving from mono_runtime_invoke() to mono_method_get_unmanaged_thunk()" or "how to call class method that takes and returns a string via thunks"

Jonathan Mitchell jonathan at mugginsoft.com
Wed Nov 11 20:41:11 UTC 2015




> On 11 Nov 2015, at 20:34, Rodrigo Kumpera <kumpera at gmail.com> wrote:
> 
> How does it crash? Did you try debugging it?
> 
> The invocation looks ok.
> 
Is It really?
From reading the runtime source comments I would have tried something like:

func(NULL, s, &monoExceptionPtr);

/**
 * mono_method_get_unmanaged_thunk:
 * @method: method to generate a thunk for.
 *
 * Returns an unmanaged->managed thunk that can be used to call
 * a managed method directly from C.
 *
 * The thunk's C signature closely matches the managed signature:
 *
 * C#: public bool Equals (object obj);
 * C:  typedef MonoBoolean (*Equals)(MonoObject*,
 *             MonoObject*, MonoException**);
 *
 * The 1st ("this") parameter must not be used with static methods:
 *
 * C#: public static bool ReferenceEquals (object a, object b);
 * C:  typedef MonoBoolean (*ReferenceEquals)(MonoObject*, MonoObject*,
 *             MonoException**);
 *
 * The last argument must be a non-null pointer of a MonoException* pointer.
 * It has "out" semantics. After invoking the thunk, *ex will be NULL if no
 * exception has been thrown in managed code. Otherwise it will point
 * to the MonoException* caught by the thunk. In this case, the result of
 * the thunk is undefined:
 *
 * MonoMethod *method = ... // MonoMethod* of System.Object.Equals
 * MonoException *ex = NULL;
 * Equals func = mono_method_get_unmanaged_thunk (method);
 * MonoBoolean res = func (thisObj, objToCompare, &ex);
 * if (ex) {
 *    // handle exception
 * }
 *
 * The calling convention of the thunk matches the platform's default
 * convention. This means that under Windows, C declarations must
 * contain the __stdcall attribute:
 *
 * C:  typedef MonoBoolean (__stdcall *Equals)(MonoObject*,
 *             MonoObject*, MonoException**);
 *
 * LIMITATIONS
 *
 * Value type arguments and return values are treated as they were objects:
 *
 * C#: public static Rectangle Intersect (Rectangle a, Rectangle b);
 * C:  typedef MonoObject* (*Intersect)(MonoObject*, MonoObject*, MonoException**);
 *
 * Arguments must be properly boxed upon trunk's invocation, while return
 * values must be unboxed.
 */

> On Wed, Nov 11, 2015 at 3:03 PM, Core_Code <julian at corecode.at> wrote:
> hello,
> 
> we are currently embedding Mono to use a C# DLL, which works fine.
> 
> we are using mono_runtime_invoke() to invoke a class method and are
> obtaining the resulting object just fine.
> 
> however, for performance reasons we'd like to switch to using the 'unmanaged
> thunks', which we did not get to work. our call differes from the example in
> the 'embedding mono' docs by the parameters and the fact that we are calling
> a class method. however we try, just different crashes.
> 
> 
> the function we have to call has this prototype:
> public static string ParseToJSON(string input)
> 
> which seems to translate to a mono method description of
> XLParser.ExcelFormulaParser:ParseToJSON (string)
> 
> we have no problem using mono_runtime_invoke() to call it exactly like this:
> 
> 
> MonoAssembly *assembly = mono_domain_assembly_open(domain,
> "/path/to/XLParser.dll");
> MonoImage *image = mono_assembly_get_image(assembly);
> MonoClass *classHandle = mono_class_from_name(image, "XLParser",
> "ExcelFormulaParser");
> const char *descAsString = "XLParser.ExcelFormulaParser:ParseToJSON
> (string)";
> MonoMethodDesc *description = mono_method_desc_new(descAsString, 0);
> method = mono_method_desc_search_in_class(description, classHandle);
> void *args[1] = {mono_string_new (domain, "A+B")};
> MonoObject *resultObject = mono_runtime_invoke(method, NULL, args, NULL);
> MonoString *resultString = mono_object_to_string(resultObject, NULL);
> char *resultCString = mono_string_to_utf8(resultString);
> 
> 
> now we are trying the thunk method:
> 
> typedef MonoObject* (*ParseToJSON) (MonoString *obj1,MonoString *obj2);
> ParseToJSON func = mono_method_get_unmanaged_thunk(method);
> MonoString *s = mono_string_new (domain, "A+B");
> MonoObject *result = func(s,NULL);
> MonoString *resultstring = mono_object_to_string(result, NULL);
> char *str = mono_string_to_utf8(resultstring);
> 
> but it crashes - any idea how to call a class method via thunks?
> 
> 
> 
> 
> --
> View this message in context: http://mono.1490590.n4.nabble.com/embedding-moving-from-mono-runtime-invoke-to-mono-method-get-unmanaged-thunk-or-how-to-call-class-me-tp4666935.html
> Sent from the Mono - General mailing list archive at Nabble.com.
> _______________________________________________
> Mono-list maillist  -  Mono-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-list
> 
> _______________________________________________
> Mono-list maillist  -  Mono-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-list



More information about the Mono-list mailing list