[Mono-list] Embedded API: Method signature not found with generic parameter
jonathan at mugginsoft.com
jonathan at mugginsoft.com
Fri Jul 12 13:06:15 UTC 2013
> You must "inflate" the generic method upon invocation.
> IIRC, there is no function in the embedded API which does this.
There is mono_class_inflate_generic_method() but this requires a MonoGenericContext.
I am attempting to call the generic method ObjectSet.ToList().
The code below employs inflation and runs to completion but returns a NULL result.
I have verified by calling non generic methods that the object does contain objects.
So something is not quite kosher yet.
// ToList() is a LINQ extension method defined in System.Core
MonoAssemblyName *monoAssemblyName = mono_assembly_name_new("System.Core");
MonoAssembly *monoSystemCoreAssembly = mono_assembly_loaded(monoAssemblyName);
mono_assembly_name_free(monoAssemblyName);
MonoType *monoType = mono_reflection_type_from_name("System.Linq.Enumerable", (MonoImage *)mono_assembly_get_image(monoSystemCoreAssembly));
MonoClass *monoClass = mono_class_from_mono_type(monoType);
if (!monoClass) abort;
const char *className = mono_class_get_name(monoClass);
[DBMonoObjectRepresentation logMonoClassInfo:monoClass];
// mono_class_get_method_from_name takes a simple method name
const char *methodName = ":ToList(System.Collections.Generic.IEnumerable`1<TSource>)";
MonoMethodDesc *methodDesc = mono_method_desc_new(methodName, YES);
while (monoClass != NULL) {
tempGenericMethod = mono_method_desc_search_in_class(methodDesc, monoClass);
if (tempGenericMethod != NULL) {
break;
}
monoClass = mono_class_get_parent(monoClass);
}
if (!tempGenericMethod) {
abort(); // fails
}
// get the generic parameter info
MonoObject *genericParameter = [self monoObject];
MonoType *genericParameterType = mono_class_get_type([self monoClass]);
NSAssert(genericParameterType, @"invalid"); // passes
//
// Inflation
//
// by reflection get MethodInfo for generic method
DBMonoEnvironment *env = [DBMonoEnvironment currentEnvironment];
MonoReflectionMethod* methodInfo = mono_method_get_object(env.monoDomain, tempGenericMethod, monoClass);
NSAssert(methodInfo, @"invalid"); // passes
// get generic helper class and method
MonoClass *helpMonoClass = [DBMonoEnvironment dumbartonMonoClassWithName:"Dumbarton.GenericHelper"];
NSAssert(helpMonoClass, @"invalid");
MonoMethod *helperMethod = mono_class_get_method_from_name(helpMonoClass, "MakeGenericMethod_1", 2);
NSAssert(helperMethod, @"invalid"); // passes
// invoke the generic helper method
MonoObject *monoException = NULL;
void *hargs [2];
hargs [0] = methodInfo;
hargs [1] = mono_type_get_object(env.monoDomain, genericParameterType);
MonoMethod *genericMethod = (MonoMethod *)mono_runtime_invoke(helperMethod, NULL, hargs, &monoException);
NSAssert(genericMethod, @"invalid"); // passes
monoException = NULL;
void *args [1];
args [0] = genericParameter;
// we are invoking a static generic method, hence the NULL
MonoObject *monoObject = mono_runtime_invoke(genericMethod, NULL, args, &monoException);
NSAssert(monoObject, @"invalid"); // fails, but the cigar awaits
Jonathan
More information about the Mono-list
mailing list