New to Reflection.Emit and need help

M

magounc

I am new to creating dynamic methods and I find that I have need to do
so. I have read through some IL and emit examples and have gotten some
simple programs to work. However, I cannot seem to use the opcode Call
correctly. This example gives me an "CLR detectd and invalid program"
exception at the line handler.invoke. I am sure the error is a simple
one. Could someone help me?

public partial class ILTest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
DynamicMethod handler = new DynamicMethod("", null, null,
typeof(ILTest).Module);
ILGenerator ilgen = handler.GetILGenerator();

MethodInfo miCall = typeof(ILTest).GetMethod("CallThis");
ilgen.Emit(OpCodes.Call, miCall);
ilgen.Emit(OpCodes.Ret);

handler.Invoke(this, null);
}

public void CallThis()
{
Response.Write("CALLED");
}
}

Thanks,
Chris Magoun
 
M

Marc Gravell

My approach: code it as I would in C#, then load that dummy assembly
into Reflector (or ILDASM) and look at the IL. Job done.

Marc
 
C

CMagoun

My approach: code it as I would in C#, then load that dummy assembly
into Reflector (or ILDASM) and look at the IL. Job done.

Marc

I appreciate the advice: you got me one step further along. I have
modified the code to this:

public partial class ILTest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
DynamicMethod handler = new DynamicMethod("", null, null,
typeof(ILTest).Module);
ILGenerator ilgen = handler.GetILGenerator();

ilgen.Emit(OpCodes.Ldarg_0);
MethodInfo miCall = typeof(ILTest).GetMethod("CallThis", new
Type[0]);
ilgen.Emit(OpCodes.Call, miCall);
ilgen.Emit(OpCodes.Ret);

handler.Invoke(this, null);
}

public void CallThis()
{
this.Response.Write("Test");
}
}

Now the CallThis code fires, but there is one problem: this == null
and I get an "object not set" exception. I thought passing this to
Invoke meant that I was to calling the function on THAT instance. Any
ideas?

Thanks,
Chris
 
C

CMagoun

Just in case anyone in the future is looking for beginning IL
generation tips and finds this post in a search, here is the answer to
my problem:

The key is to realize that all methods created with DynamicMethod are
static and thus, it makes sense that the <this> pointer == null. To
call the method on the desired instance, I have to pass it as a
parameter of the dynamic method like this:

public partial class ILTest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//THIS LINE CHANGED
DynamicMethod handler = new DynamicMethod("", null, new Type[]
{typeof(ILTest)}, typeof(ILTest).Module);
ILGenerator ilgen = handler.GetILGenerator();

ilgen.Emit(OpCodes.Ldarg_0);

MethodInfo miCall = typeof(ILTest).GetMethod("CallThis");
ilgen.Emit(OpCodes.Call, miCall);
ilgen.Emit(OpCodes.Ret);

//THIS LINE CHANGED
handler.Invoke(null, new Object[] {this});
}

public void CallThis()
{
this.Response.Write("Test");
}
}

Notice the DynamicMethod will now take a single argument of type
ILTest, and that when I Invoke the method, I don't bind it to an
instance, but instead pass the desired <this> pointer as a parameter.
This code works and invokes the dynamic method on the correct form
instance.

Thanks,
Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top