[Mono-list] Embedded API: Method signature not found with generic parameter
mugginsoft
jonathan at mugginsoft.com
Mon Jul 15 21:08:42 UTC 2013
Just to give the completed test code:
// Obj-C
- (MonoObject *)execute
{
// get a reference to the System.Core assembly
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;
//[DBMonoObjectRepresentation logMonoClassInfo:monoClass];
// ToList is an extension method defined as a static method on
System.Linq.Enumerable
// mono_class_get_method_from_name takes a simple method name
const char *methodName = "ToList";
MonoMethod *tempGenericMethod =
mono_class_get_method_from_name(monoClass, methodName, 1);
if (!tempGenericMethod) {
abort(); // passes
}
// get the method by descriptor
tempGenericMethod = nil;
// note the method looses the generic suffix
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(); // passes
}
// by reflection get MethodInfo for generic method
DBMonoEnvironment *env = [DBMonoEnvironment currentEnvironment];
MonoReflectionMethod* methodInfo =
mono_method_get_object(env.monoDomain, tempGenericMethod, monoClass);
NSAssert(methodInfo, @"invalid");
// get generic helper class
MonoClass *helpMonoClass = [DBMonoEnvironment
dumbartonMonoClassWithName:"Dumbarton.GenericHelper"];
NSAssert(helpMonoClass, @"invalid");
// get method to retrieve generic argument type at index
MonoMethod *genericArgTypehelperMethod =
mono_class_get_method_from_name(helpMonoClass, "GenericArgumentTypeAtIndex",
2);
NSAssert(genericArgTypehelperMethod, @"invalid");
// get generic method parameter type info
MonoObject *monoException = NULL;
int idx = 0;
MonoType *t = mono_class_get_type([self monoClass]); // say ObjectSet
NSLog(@"Class type name : %s", mono_type_get_name(t));
void *hargs [2];
hargs [0] = mono_type_get_object(env.monoDomain, t);
hargs [1] = &idx;
MonoObject *boxedGenericType =
mono_runtime_invoke(genericArgTypehelperMethod, NULL, hargs,
&monoException);
NSAssert(boxedGenericType, @"invalid");
MonoType *genericParameterType = *(MonoType**) mono_object_unbox
(boxedGenericType);
MonoMethod *helperMethod =
mono_class_get_method_from_name(helpMonoClass, "MakeGenericMethod_1", 2);
NSAssert(helperMethod, @"invalid");
// invoke the generic helper method
monoException = NULL;
hargs [0] = methodInfo;
hargs [1] = mono_type_get_object(env.monoDomain, genericParameterType);
MonoObject *boxedGenericMethod = mono_runtime_invoke(helperMethod, NULL,
hargs, &monoException);
/*
mono_runtime_invoke always a returns a MonoObject *.
Un boxing gives us a pointer to the value, a MonoMethod*.
Dereferencing this gives the method pointer.
*/
MonoMethod *genericMethod = *(MonoMethod**) mono_object_unbox
(boxedGenericMethod);
NSAssert(genericMethod, @"invalid");
monoException = NULL;
void *args [1];
args [0] = [self monoObject]; // an instance of say ObjectSet
MonoObject *monoObject = mono_runtime_invoke(genericMethod, NULL, args,
&monoException);
NSAssert(monoObject, @"invalid");
MonoClass *resultMonoClass = mono_object_get_class(monoObject);
MonoType *resultTypeName = mono_class_get_type(resultMonoClass);
NSLog(@"Result type name : %s", mono_type_get_name(resultTypeName));
return monoObject;
}
// Mono helper
using System;
using System.Reflection;
using System.Collections;
namespace Dumbarton
{
public class GenericHelper
{
//
// Generic method helpers
//
public static IntPtr MakeGenericMethod(MethodInfo method, Type[] parms)
{
// See MSDN's MethodInfo.MakeGenericMethod docs
MethodInfo methodInfo = method.MakeGenericMethod (parms);
return methodInfo.MethodHandle.Value;
}
public static IntPtr MakeGenericMethod_1(MethodInfo method, Type parm0)
{
MethodInfo methodInfo = method.MakeGenericMethod (parm0);
return methodInfo.MethodHandle.Value;
}
public static IntPtr MakeGenericMethod_2(MethodInfo method, Type parm0,
Type parm1)
{
MethodInfo methodInfo = method.MakeGenericMethod (parm0, parm1);
return methodInfo.MethodHandle.Value;
}
public static IntPtr MakeGenericMethod_3(MethodInfo method, Type parm0,
Type parm1, Type parm2)
{
MethodInfo methodInfo = method.MakeGenericMethod (parm0, parm1, parm2);
return methodInfo.MethodHandle.Value;
}
//
// Generic argument helpers
//
private static Type[] GenericArgumentTypes(Type t)
{
Type[] types = null;
if (t.ContainsGenericParameters) {
types = t.GetGenericArguments ();
}
return types;
}
public static IntPtr GenericArgumentTypeAtIndex(Type t, int index)
{
IntPtr ptrType = new IntPtr(0);
Type[] genericTypes = t.GetGenericArguments();
if (genericTypes != null & index < genericTypes.Length) {
Type argType = genericTypes[index];
ptrType = argType.TypeHandle.Value;
}
return ptrType;
}
}
}
--
View this message in context: http://mono.1490590.n4.nabble.com/Embedded-API-Method-signature-not-found-with-generic-parameter-tp4660157p4660215.html
Sent from the Mono - General mailing list archive at Nabble.com.
More information about the Mono-list
mailing list