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.
精彩评论