I want to call a function with a parameter with the reflection.emit
API. In the following is what I have at the moment. But when I run it, it throws the following exception: System.InvalidProgramException : Common Language Runtime detected an invalid program
. So my question is what I have wrong in my code snippet below? Can someone help me out?
public class Test
{
public void test()
{
Func<int, long> realSquareFunc = (val) => val * val;
Type[] methodArgs = { typeof(int) };
DynamicMethod squareIt = new DynamicMethod(
"SquareIt",
typeof(long),
methodArgs,
typeof(Test).Module)
;
ILGenerator il = squareIt.GetILGenerator();
il.Emit(OpCodes.Ldarg_0); // Save parameter on stack
il.Emit(OpCodes.Call, realSquareFunc.Method); // Call function with input as parameter
il.Emit(OpCodes.Ret); // Return value from function call before
var myMethod = (Func<int, long>)squareIt.CreateDelegate(realSquareFunc.GetType());
var result = myMethod.Invoke(4); // Should be 16 (4*4)
}
}
如果被调用的方法是静态方法,您的代码将按原样工作:
However, the
realSquareFunc = (val) => val * val
lambda is actually compiled as an instance method of a hidden class. To call an instance method, the instance must be pushed onto the stack first, before the method arguments. Instance method calls also typically use theCallvirt
opcode (regardless of whether they're virtual, because this opcode does null reference checking):由于涉及到编译器生成的类,因此直接调用lambda的target方法更为复杂,但是如果您通常要调用委托,则它的工作方式如下: