I am having trouble figuring out how to call generic method (both static and non-static) from C.
The biggest culprit is that calling generic methods is essentially undocumented, there are no examples in the mono repository but there's a mention that this is supposedly possible in the docs:
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); Unfortunately this is not that helpful since it doesn't show a complete example, and no matter what I do (using mono_object_get_class or not) I end up with a warning followed by a crash when calling generic methods.
* Assertion: should not be reached at marshal.c:4315 SIGABRT stracktrace... Below a sample C# class and C code calling into it. Invoking non-generic methods works just fine but I have no clue how to invoke generic methods. I'd appreciate any tips that could help.
Sample 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); } } } Sample 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; }