mercredi 15 juin 2016

Call other method in IlGenerator

I'm building my own type via TypeBuilder and I'm trying to add to this methods that will call methodInfo gathered from different object.

The problem is I don't know how to use ILGenerator.Emit or ILGenerator.EmitCall.

I've tried to use il.EmitCall(OpCodes.Call, methodInfo, arguments) and il.Emit(OpCodes.Call, methodInfo) but neither of them worked. Always I got this error:

[InvalidProgramException: Common Language Runtime detected an invalid program.]
   MyImplementationController.Hello1() +0

[TargetInvocationException: Exception has been thrown by the target of an invocation.]
   System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) +0
   System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) +192
   System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +155
   System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters) +19

And this is my code:

        foreach (var methodInfo in methodInfosFromSomewhere)
        {
            var arguments = methodInfo.GetParameters().Select(a => a.ParameterType).ToArray();
            MethodBuilder mb = tb.DefineMethod(
                methodInfo.Name,
                MethodAttributes.Final | MethodAttributes.Public,
                CallingConventions.HasThis,
                methodInfo.ReturnType,
                arguments);

            // method 
            ILGenerator il = mb.GetILGenerator();
            int numParams = arguments.Length;
            for (byte x = 0; x < numParams; x++)
            {
                //il.Emit(OpCodes.Ldarg_S, x);
                il.Emit(OpCodes.Ldstr, x);
            }
            //il.EmitCall(OpCodes.Call, methodInfo, arguments);
            il.Emit(OpCodes.Call, methodInfo);

            il.Emit(OpCodes.Ret);
        }





Aucun commentaire:

Enregistrer un commentaire