[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