none
ILGenerator : call DynamicMethod with Emit method

    Question

  • A sample of what I try to do :

        class Program
        {
            static void Main(string[] args)
            {
                GenerationIL();
            }

            public static void GenerationIL()
            {
                Action oDynamicMethod = DynamicMethod();

                DynamicMethod dm = new DynamicMethod("Run", null, Type.EmptyTypes);
                ILGenerator oILGenerator = dm.GetILGenerator();

                oILGenerator.Emit(OpCodes.Call, oDynamicMethod.Method); // Runtime ERROR
                oILGenerator.Emit(OpCodes.Ret);

                ((Action)dm.CreateDelegate(typeof(Action))).Invoke();
            }

            public static Action DynamicMethod()
            {
                DynamicMethod dm = new DynamicMethod("Todo", null, Type.EmptyTypes);

                ILGenerator oILGenerator = dm.GetILGenerator();
                oILGenerator.EmitWriteLine("Todo content");
                oILGenerator.Emit(OpCodes.Ret);

                return (Action)dm.CreateDelegate(typeof(Action));
            }
        }

    The error that I have is "MethodInfo must be a RuntimeMethodInfo."
    Is there any way to Call a method handler ?

    Thanks

    Sebastien
    Thursday, March 04, 2010 7:57 AM

Answers

  • Playing around with this a little, I found that I could get this working as long as I passed the actual DynamicMethod to the call instead of Delegate.Method property.
    It appears that the ILGenerator.Emit method has a hardcoded check to see if it a DynamicMethod or a RuntimeMethodInfo (ie a real 'MethodInfo'). If it's neither it throws. Unfortunately, the method in the delegate returned from DynamicMethod.CreateDelegate is actually neither of these two (it's a instance of an internal RTDynamicMethod which deries directly from MethodInfo).

    I'm not sure whether this is the correct behavior and when I get back into the office I will check with the team that owns Reflection. Either way, the workaround today is pass the DynamicMethod directly to ILGenerator.Emit(OpCodes.Call, MethodInfo) instead of the Delegate.Method.
    Base Class Library Team (BCL) | My Blog: http://davesbox.com
    Thursday, March 04, 2010 4:45 PM
    Moderator

All replies

  • Playing around with this a little, I found that I could get this working as long as I passed the actual DynamicMethod to the call instead of Delegate.Method property.
    It appears that the ILGenerator.Emit method has a hardcoded check to see if it a DynamicMethod or a RuntimeMethodInfo (ie a real 'MethodInfo'). If it's neither it throws. Unfortunately, the method in the delegate returned from DynamicMethod.CreateDelegate is actually neither of these two (it's a instance of an internal RTDynamicMethod which deries directly from MethodInfo).

    I'm not sure whether this is the correct behavior and when I get back into the office I will check with the team that owns Reflection. Either way, the workaround today is pass the DynamicMethod directly to ILGenerator.Emit(OpCodes.Call, MethodInfo) instead of the Delegate.Method.
    Base Class Library Team (BCL) | My Blog: http://davesbox.com
    Thursday, March 04, 2010 4:45 PM
    Moderator
  • Thank you for your help.
    But if you have more information or remarks on it, it could be useful.
    Friday, March 05, 2010 9:14 AM
  • I've forwarded the question on, I'll reply back here when I get a response. I suggest you keep this question marked as unanswered until then so that we don't lose track of it.


    Base Class Library Team (BCL) | My Blog: http://davesbox.com
    Friday, March 05, 2010 6:00 PM
    Moderator
  • OK thanks.
    Saturday, March 06, 2010 8:24 AM
  • Okay, talked to the owner of this class, he agrees that this is a limitation that we might be able to fix in a future version. I've filed a bug internally and we'll consider it for a future version of the .NET Framework.
    Base Class Library Team (BCL) | My Blog: http://davesbox.com
    Monday, March 15, 2010 5:37 PM
    Moderator
  • OK, Thanks.
    Call directly the DynamicMethod instance works well in my case. So I will update the code with next .NET framework version.
    Wednesday, March 17, 2010 8:35 AM