Skip to main content
gamedev.net
🔒 Locked

[.net] Calling Instance Method Using ILGenerator.Emit

Started by NickGravelyn 1 reply 8k views
Original Post
NickGravelyn
NickGravelyn
I'm trying to get started with dynamic code using Reflection.Emit and I'm kind of stuck. I managed to write a simple DynamicMethod that just added two parameters together. That worked fine. Then I made a custom type (not dynamic) and created a DynamicMethod that created a new type using parameters and returned it. Again, that worked. Now I'm trying to expand on the second one and call a method on that object. So I created a method in my type that takes an integer and updates the type. Unfortunately I must've done something wrong, because it's not working. Here's what I have:

//push the two arguments onto the stack
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldarg_1);

//create the new object using the two arguments
gen.Emit(OpCodes.Newobj, typeof(MyClass).GetConstructor(new Type[] { typeof(int), typeof(string) }));
			
//push the int argument onto the stack twice
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldarg_0);

//add them together
gen.Emit(OpCodes.Add);

//call the method to change the value
gen.Emit(OpCodes.Call, typeof(MyClass).GetMethod("ChangeInt", new Type[] { typeof(int) }));

//remove the top value from the stack to get our object
gen.Emit(OpCodes.Pop);

//return the object
gen.Emit(OpCodes.Ret);

If I comment out the gen.Emit(OpCodes.Call,... line it works just fine. So I'm wondering if I formed that incorrectly. I have the instance on the stack with the parameter on top of that. Then I call the method. But when I execute the DynamicMethod it throws an exception (which unfortunately doesn't give much help). Any ideas? [Edited by - NickGravelyn on August 9, 2007 3:34:34 PM]
turnpast
turnpast
To call an instance method the object reference needs to be on the stack before the the arguments to the method. You may also want to use EmitCall instead of emit, not entirely sure. I find IL generally a pain and when I have to use it directly I typically write the code out in C#, compile it and use ildasm to see what the compiler generates.

hope this helps.
Mike.Popoloski
Mike.Popoloski
Writing your dynamic types in IL is indeed very tedious. Why not use the CodeDOM to write your dynamic code as C# and compile it on the fly? Same level of flexibility, but a much much much better experience and ease of use.
Mike Popoloski | Journal | SlimDX

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.