c# c mono mono-embedding

Incrustación mono, llame a un método genérico C#de C



mono-embedding (1)

No puede invocar métodos genéricos de esa manera y, lamentablemente, la documentación es un poco engañosa. Si desea invocar public void GenericMember<T>(T t) con un parámetro String , debe encontrar el método con la firma public void GenericMember<String>(String t) y usar mono_runtime_invoke en él.

La forma más sencilla de hacerlo es utilizar el método MethodInfo.MakeGenericMethod a través de un método de utilidad C #:

public static IntPtr Utility(MethodInfo method, Type type) { return method.MakeGenericMethod(type).MethodHandle.Value; }

Usando la API Mono integrada, encuentre el método de Utility , MonoMethod* con el MonoMethod* representa el GenericMethod<T>(T t) y el tipo que desea (String en su ejemplo). El retorno de esta invocación será un MonoMethod* que representará GenericMethod<String>(String t) . Este es el método que necesita invocar.

Hice una publicación detallada con el código fuente aquí .

Tengo problemas para averiguar cómo llamar al método genérico (tanto estático como no estático) de C.

El principal culpable es que llamar a los métodos genéricos es esencialmente indocumentado, no hay ejemplos en el repositorio mono pero hay una mención de que esto es supuestamente posible en los documentos:

If you want to invoke generic methods, you must call the method on the "inflated" class, which you can obtain from the mono_object_get_class() MonoClass *clazz; MonoMethod *method; clazz = mono_object_get_class (obj); /* * If there are more Add methods declared, you * may use mono_method_desc_search_in_class (clazz, ":Add(T)"), * you must substitute ":Add(T)" with the correct type, for example * for List<int>, you would use ":Add(int)". */ method = mono_class_get_method_from_name (clazz, "Add", 1); mono_runtime_invoke (method, obj, args, &exception);

Lamentablemente, esto no es tan útil, ya que no muestra un ejemplo completo, y no importa lo que hago (utilizando mono_object_get_class o no) termino con una advertencia seguida de un bloqueo al llamar a métodos genéricos.

* Assertion: should not be reached at marshal.c:4315 SIGABRT stracktrace...

Debajo de una muestra de clase de C # y un código de C para invocarlo. Invocar métodos no genéricos funciona bien, pero no tengo idea de cómo invocar métodos genéricos. Agradecería cualquier consejo que pueda ayudar.

Ejemplo CSharp

namespace foo { class MainClass { public static void Main(string[] args) { Console.WriteLine("Main"); } public void GenericMember<T>(T t) { Console.WriteLine(t); } public static void GenericStatic<T>(T t) { Console.WriteLine(t); } public void NonGenericMember(string t) { Console.WriteLine(t); } public static void NonGenericStatic(string t) { Console.WriteLine(t); } } }

Muestra C

#include <mono/jit/jit.h> #include <mono/metadata/mono-config.h> #include <mono/metadata/metadata.h> #include <mono/metadata/appdomain.h> #include <mono/metadata/class.h> #include <mono/metadata/assembly.h> #include <mono/metadata/image.h> #include <mono/metadata/object.h> #include <mono/metadata/debug-helpers.h> int main(int argc, char **argv) { mono_config_parse(NULL); MonoDomain *domain = mono_jit_init_version("app", "v4.0.30319"); MonoAssembly *assembly = mono_domain_assembly_open(domain, "foo.exe"); MonoImage *image = mono_assembly_get_image(assembly); mono_jit_exec(domain, assembly, argc, argv); MonoClass *klass = mono_class_from_name(image, "foo", "MainClass"); MonoObject *instance = mono_object_new(domain, klass) MonoString *string = mono_string_new(domain, "hello"); void *params[] = { string }; //NonGenericStatic call (works) MonoMethod *method = mono_class_get_method_from_name(klass, "NonGenericStatic", 1); mono_runtime_invoke(method, NULL, params, NULL); //NonGenericMember call (works); method = mono_class_get_method_from(klass, "NonGenericMember", 1); mono_runtime_invoke(method, instance, params, NULL); //GenericStatic call (fails) method = mono_class_get_method_from_name(klass, "GenericStatic", 1); mono_runtime_invoke(method, NULL, params, NULL); //GenericMember call (fails) method = mono_class_get_method_from_name(klass, "GenericMember", 1); mono_runtime_invoke(method, instance, params, NULL); mono_jit_cleanup(domain, assembly); return 0; }