Search code examples
c#.netdelegatesreflection.emitintermediate-language

ILGenerator: Load created method


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?


Solution

  • 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);