开发者

ILGenerator: Load created method

开发者 https://www.devze.com 2023-01-28 07:04 出处:网络
I am using System.Reflection.Emit, and at some point I want to create a delegate from a MethodBuilder:

I am using System.Reflection.Emit, and at some point I want to create a delegate from a MethodBuilder:

MethodBuilder fooBuilder = createFooMethodBuilder();
ILGenerator ilGenerator = ...
Type delegateType = typeof(DelegateType);
LocalBuilder delegateVar = ilGenerator.DeclareLocal(delegateType);
//Somehow create emit instructions to create delegate from fooBuilder
//Store delegate in delegateVar using 

I could find out that to 开发者_开发百科create delegates from static functions something like this is used:

ldnull 
ldftn void class Test.MainClass::bar()
newobj instance void class Test.DelegateType::'.ctor'(object, native int)

But now I'm stuck. I need a way to ldftn the MethodBuilder and then I need a way to emit the instruction for the following line. And I have no idea how to get a constructor that accepts a native int.

Any suggestions?


A native int is an IntPtr in C#.

You can get the ConstructorInfo for the delegate type using Type.GetConstructor:

var constructorInfo =
    delegateType.GetConstructor(new Type[] { typeof(object), typeof(IntPtr) });

Then you can emit the IL instructions like this:

il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Ldftn, someMethodInfo);
il.Emit(OpCodes.Newobj, constructorInfo);


The ILGenerator class has an Emit overload that takes a methodinfo, so you can do something like ilGenerator.Emit(Opcodes.ldftn, mi), where mi is the method you want to call. It can be any method you found with the reflection API, or even another method you created with a MethodBuilder (it derives from MethodInfo).

Similarly, to call a constructor you would emit a newobj instruction providing a ConstructorInfo for the target overload.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号