I want to create a simple dynamic method that returns square of a integer number(i.e - If number is 5, it should return 25).
I have written the code below:-
class Square
{
public int CalculateSquare(int value)
{ return value * value; }
}
public class DynamicMethodExample
{
private delegate int SquareDelegate(int value);
internal void CreateDynamicMethod()
{
MethodInfo getSquare = typeof(Square).GetMethod("CalculateSquare");
DynamicMethod calculateSquare = new DynamicMethod("CalculateSquare",
typeof(int),new Type[]{typeof(int)});
ILGenerator il = calculateSquare.GetILGenerator();
// Load the first argument, which is a integer, onto the stack.
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Mul);
// Call the overload of CalculateSquare that returns the square of number
il.EmitCall(OpCodes.Call, getSquare,null);
il.Emit(OpCodes.Ret);
SquareDelegate hi =
(SquareDelegate)calculateSquare.CreateDelegate(typeof(SquareDelegate));
Console.WriteLine("\r\nUse the delegate to execute the dynamic method:");
int retval = hi(42);
Console.WriteLine("Calculate square returned " + retval);
}
}
Why am I getting "InvalidProgramException" at
int retval = hi(42);
How can I get this thing to work?
You have a couple of issues. First, the Square class must be public, and its CalculateSquare method must be static. Second, you don't want to emit a Mul if you are calling the method to multiply. Here's your code with those fixes:
public class Square
{
public static int CalculateSquare( int value )
{ return value * value; }
}
public class DynamicMethodExample
{
private delegate int SquareDelegate( int value );
internal void CreateDynamicMethod()
{
MethodInfo getSquare = typeof( Square ).GetMethod( "CalculateSquare" );
DynamicMethod calculateSquare = new DynamicMethod( "CalculateSquare",
typeof( int ), new Type[] { typeof( int ) } );
ILGenerator il = calculateSquare.GetILGenerator();
// Load the first argument, which is a integer, onto the stack.
il.Emit( OpCodes.Ldarg_0 );
// Call the overload of CalculateSquare that returns the square of number
il.Emit( OpCodes.Call, getSquare );
il.Emit( OpCodes.Ret );
SquareDelegate hi =
( SquareDelegate )calculateSquare.CreateDelegate( typeof( SquareDelegate ) );
Console.WriteLine( "\r\nUse the delegate to execute the dynamic method:" );
int retval = hi( 42 );
Console.WriteLine( "Calculate square returned " + retval );
}
}