Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. LCG issue (DynamicMethod / ILGenerator)

LCG issue (DynamicMethod / ILGenerator)

Scheduled Pinned Locked Moved C#
helpdotnettutorialquestionannouncement
11 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    rcollina
    wrote on last edited by
    #1

    I have the same thread in the MSDN forums, but sadly no one has replied so far. I hope that someone can help me out here :) Upon invoking a Delegate created from a DynamicMethod, I receive the following error "Common Language Runtime detected an invalid program.". It's a bit hard to shape the problem verbally, but I'll try my best, since I would need to post a lot of source code - however, here's my got at it: I have a Method Manager class. This class allows me to story a collection of MethodInfo objects into a Dictionary object, whose key is a Type. class MethodInfoCollection: List { ... } Dictionary m_Methods; ...etc Let's say I'd want to call a specific method for each Key of this m_Methods Dictionary. I would iterate into each MethodInfoCollection and then into each MethodInfo object, checking if the names matche, and then executing via Invoke(); . These MethodInfo objects are coming from different objects instances. CallMethod("Update"); // this calls every "Update" method found in the m_Methods collection. Since MethodInfo.Invoke() is way much too slow for my needs, I thought I could come up with another method, that is using DynamicMethods. I already have a List (m_InterfaceMethods) containing all the possible method names (like "Update" in the above CallMethod call). My intent is to create a lookup table of Delegates. So, it would be a delegate void SpecificDelegate(); Dictionary m_MSILMethods; - for every known method name, there will be a dynamically created method which in turn will call all the methods - whose names are matching the string Key. I hope this is clear enough.

    public static void CallMethod(string MethodName)
    {
    
       m_MSILMethods[MethodName].Invoke();
       // m_MSILMethods[MethodName].Invoke(); should act like this:
       // [pseudocode]
       // Call ObjectA.MethodName;
       // Call ObjectB.MethodName;
       // Call ObjectC.MethodName;
       // ...and so on. instead of having a slow MethodInfo.Invoke() call in a foreach loop each time.
    
    }
    

    How to create a DynamicMethod which will invoke in its IL a series of methods? Those methods are stored in a MethodInfo class. Which instructions do I require for it to work? MSIL Method Generator:

    DynamicMethod m_MSILMethod;
    ILGenerator m_ILGenerator;
    
    foreach (string m_InterfaceMethod in m_InterfaceMethods)
    {
    
    [...]
    
    m_MS
    
    S 1 Reply Last reply
    0
    • R rcollina

      I have the same thread in the MSDN forums, but sadly no one has replied so far. I hope that someone can help me out here :) Upon invoking a Delegate created from a DynamicMethod, I receive the following error "Common Language Runtime detected an invalid program.". It's a bit hard to shape the problem verbally, but I'll try my best, since I would need to post a lot of source code - however, here's my got at it: I have a Method Manager class. This class allows me to story a collection of MethodInfo objects into a Dictionary object, whose key is a Type. class MethodInfoCollection: List { ... } Dictionary m_Methods; ...etc Let's say I'd want to call a specific method for each Key of this m_Methods Dictionary. I would iterate into each MethodInfoCollection and then into each MethodInfo object, checking if the names matche, and then executing via Invoke(); . These MethodInfo objects are coming from different objects instances. CallMethod("Update"); // this calls every "Update" method found in the m_Methods collection. Since MethodInfo.Invoke() is way much too slow for my needs, I thought I could come up with another method, that is using DynamicMethods. I already have a List (m_InterfaceMethods) containing all the possible method names (like "Update" in the above CallMethod call). My intent is to create a lookup table of Delegates. So, it would be a delegate void SpecificDelegate(); Dictionary m_MSILMethods; - for every known method name, there will be a dynamically created method which in turn will call all the methods - whose names are matching the string Key. I hope this is clear enough.

      public static void CallMethod(string MethodName)
      {
      
         m_MSILMethods[MethodName].Invoke();
         // m_MSILMethods[MethodName].Invoke(); should act like this:
         // [pseudocode]
         // Call ObjectA.MethodName;
         // Call ObjectB.MethodName;
         // Call ObjectC.MethodName;
         // ...and so on. instead of having a slow MethodInfo.Invoke() call in a foreach loop each time.
      
      }
      

      How to create a DynamicMethod which will invoke in its IL a series of methods? Those methods are stored in a MethodInfo class. Which instructions do I require for it to work? MSIL Method Generator:

      DynamicMethod m_MSILMethod;
      ILGenerator m_ILGenerator;
      
      foreach (string m_InterfaceMethod in m_InterfaceMethods)
      {
      
      [...]
      
      m_MS
      
      S Offline
      S Offline
      S Senthil Kumar
      wrote on last edited by
      #2

      I was able to reproduce your problem and figure out the offending IL statement. It's the m_ILGenerator.Emit(OpCodes.Ldnull); before you emit the ret statement. Let me know if it still reports invalid programs after you removed the statement.

      Regards Senthil [MVP - Visual C#] _____________________________ My Blog | My Articles | My Flickr | WinMacro

      R 1 Reply Last reply
      0
      • S S Senthil Kumar

        I was able to reproduce your problem and figure out the offending IL statement. It's the m_ILGenerator.Emit(OpCodes.Ldnull); before you emit the ret statement. Let me know if it still reports invalid programs after you removed the statement.

        Regards Senthil [MVP - Visual C#] _____________________________ My Blog | My Articles | My Flickr | WinMacro

        R Offline
        R Offline
        rcollina
        wrote on last edited by
        #3

        Thanks, I'll check this as soon as I get home.:) Edit: By removing ldnull I get a unhandled AccessViolationException, exactly where DynamicMethod.Invoke is called. "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." Is my idea feasible or perhaps there's something wrong in my dynamic method creation routine? The code above has been stripped and reduced from the original version. Thanks in advance for any help. Edit 2: I guess Ldnull is needed since the return value is of type "void". Those ld_arg0 instructions don't seem correct to me, but then again, I don't know which specific instructions I should call in order to call the methods of the proper objects. -- modified at 19:13 Friday 12th January, 2007

        S 1 Reply Last reply
        0
        • R rcollina

          Thanks, I'll check this as soon as I get home.:) Edit: By removing ldnull I get a unhandled AccessViolationException, exactly where DynamicMethod.Invoke is called. "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." Is my idea feasible or perhaps there's something wrong in my dynamic method creation routine? The code above has been stripped and reduced from the original version. Thanks in advance for any help. Edit 2: I guess Ldnull is needed since the return value is of type "void". Those ld_arg0 instructions don't seem correct to me, but then again, I don't know which specific instructions I should call in order to call the methods of the proper objects. -- modified at 19:13 Friday 12th January, 2007

          S Offline
          S Offline
          S Senthil Kumar
          wrote on last edited by
          #4

          Roberto Collina wrote:

          By removing ldnull I get a unhandled AccessViolationException, exactly where DynamicMethod.Invoke is called. "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

          That's a strange error for a managed application. Do any of the invoked methods end up calling unmanaged code?

          Roberto Collina wrote:

          Edit 2: I guess Ldnull is needed since the return value is of type "void".

          No, it's not. Here's the IL dump generated by ildasm for a simple method that prints "Hello" to the console.

          .method public hidebysig instance void TestMethod() cil managed
          {
          // Code size 13 (0xd)
          .maxstack 8
          IL_0000: nop
          IL_0001: ldstr "Hello"
          IL_0006: call void [mscorlib]System.Console::WriteLine(string)
          IL_000b: nop
          IL_000c: ret
          } // end of method Program::TestMethod

          You can see that there is no ldnull instruction before the ret statement. Could you try running the following program? It is the test program I tried for reproducing your problem.

          public class Program
          {
          delegate void MyDelegate();
          public void TestMethod(){Console.WriteLine("Hello");}
          public static void Main()
          {
          Program p = new Program();
          MethodInfo methodInfo = p.GetType().GetMethod("TestMethod");
          DynamicMethod dynMethod = new DynamicMethod("DynTestMethod", null, null, typeof(Program));
          ILGenerator gen = dynMethod.GetILGenerator();
          gen.Emit(OpCodes.Ldarg_0);
          gen.Emit(OpCodes.Call, methodInfo);
          //gen.Emit(OpCodes.Ldnull); // If you uncomment, you'll get InvalidProgramException
          gen.Emit(OpCodes.Ret);
          MyDelegate d = (MyDelegate)dynMethod.CreateDelegate(typeof(MyDelegate));
          d.Invoke();
          }
          }

          As you can see, it generates DynTestMethod, which simply forwards the call to TestMethod. If this works for you, then you can be sure that the IL generation part is correct. Also, are any of your MethodInfo's static? If they are, then OpCodes.Ldarg_0 should not be emitted for those methods. That statement is for passing the this parameter and it should not be passed to static methods.

          Regards Senthil [MVP - Visual C#] _____________________________

          R 1 Reply Last reply
          0
          • S S Senthil Kumar

            Roberto Collina wrote:

            By removing ldnull I get a unhandled AccessViolationException, exactly where DynamicMethod.Invoke is called. "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

            That's a strange error for a managed application. Do any of the invoked methods end up calling unmanaged code?

            Roberto Collina wrote:

            Edit 2: I guess Ldnull is needed since the return value is of type "void".

            No, it's not. Here's the IL dump generated by ildasm for a simple method that prints "Hello" to the console.

            .method public hidebysig instance void TestMethod() cil managed
            {
            // Code size 13 (0xd)
            .maxstack 8
            IL_0000: nop
            IL_0001: ldstr "Hello"
            IL_0006: call void [mscorlib]System.Console::WriteLine(string)
            IL_000b: nop
            IL_000c: ret
            } // end of method Program::TestMethod

            You can see that there is no ldnull instruction before the ret statement. Could you try running the following program? It is the test program I tried for reproducing your problem.

            public class Program
            {
            delegate void MyDelegate();
            public void TestMethod(){Console.WriteLine("Hello");}
            public static void Main()
            {
            Program p = new Program();
            MethodInfo methodInfo = p.GetType().GetMethod("TestMethod");
            DynamicMethod dynMethod = new DynamicMethod("DynTestMethod", null, null, typeof(Program));
            ILGenerator gen = dynMethod.GetILGenerator();
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Call, methodInfo);
            //gen.Emit(OpCodes.Ldnull); // If you uncomment, you'll get InvalidProgramException
            gen.Emit(OpCodes.Ret);
            MyDelegate d = (MyDelegate)dynMethod.CreateDelegate(typeof(MyDelegate));
            d.Invoke();
            }
            }

            As you can see, it generates DynTestMethod, which simply forwards the call to TestMethod. If this works for you, then you can be sure that the IL generation part is correct. Also, are any of your MethodInfo's static? If they are, then OpCodes.Ldarg_0 should not be emitted for those methods. That statement is for passing the this parameter and it should not be passed to static methods.

            Regards Senthil [MVP - Visual C#] _____________________________

            R Offline
            R Offline
            rcollina
            wrote on last edited by
            #5

            Shame on me I didn't notice your reply. First of all, thanks for your valuable help! I stand corrected about the Ldnull, as I've been doing a test very similar to yours and it gave me the same result. I was linking "void" to a null push to the stack before the ret statement. Funny, but not working. :) I have reproduced the AccessViolationException by adding many "ld_arg0" instructions.

            			gen.Emit(OpCodes.Ldarg_0);
            			gen.Emit(OpCodes.Call, methodInfo);
            			gen.Emit(OpCodes.Ldarg_0);
            			gen.Emit(OpCodes.Call, methodInfo);
            

            I was trying to call the same method twice in your example. I've already found two bugs in my IL generation methods thanks to you. Here's the problem showing the key to my initial idea:

            	public class Program
            	{
            		delegate void MyDelegate();
            		public void TestMethod() { Console.WriteLine("Hello"); }
            		public void TestMethod2() { Console.WriteLine("hey"); }
            		public static void Main()
            		{
            			Program p = new Program();
            			MethodInfo methodInfo = p.GetType().GetMethod("TestMethod");
            			MethodInfo methodInfo2 = p.GetType().GetMethod("TestMethod2");
            
            			DynamicMethod dynMethod = new DynamicMethod("DynTestMethod", 
                                        null, null, typeof(Program));
            
            			ILGenerator gen = dynMethod.GetILGenerator();
            
            			gen.Emit(OpCodes.Ldarg_0);
            			gen.Emit(OpCodes.Call, methodInfo);
            
            			//IL instruction missing here
            			gen.Emit(OpCodes.Call, methodInfo2); //Most likely to produce the exception.
            
            			gen.Emit(OpCodes.Ret);
            
            			MyDelegate d = (MyDelegate)dynMethod.CreateDelegate(typeof(MyDelegate));
            			d.Invoke();
            			Console.ReadLine();
            
            		}
            	}
            

            The program gives an "InvalidProgramException" as expected. I wonder if there's a way to make that second Call instruction work. And others, if need be. Many thanks again for your help and sorry for the delay of this reply. Roberto Edit: here's another pseudo-msil dump of what I'm trying to get to run:

            .method void ManagedProcessInput 
            {
            	ldarg_0
            	call void UserInterface.ProcessInput()
            	call void UserInterfaceEditor.ProcessInput()
            	ret
            }
            

            Note: the methods stored in the MethodInfos are not static. Moreover, they are implementations of an interface.

            interface IMyInterface
            {
               void Run();
            }
            
            class MyObject : IMyInterface
            {
               [ctor / dtor]
               public void Run()
               {
                  [impl. here]
               }
            }
            

            -- modified at 20:04 Saturday 13th January, 2007

            S 1 Reply Last reply
            0
            • R rcollina

              Shame on me I didn't notice your reply. First of all, thanks for your valuable help! I stand corrected about the Ldnull, as I've been doing a test very similar to yours and it gave me the same result. I was linking "void" to a null push to the stack before the ret statement. Funny, but not working. :) I have reproduced the AccessViolationException by adding many "ld_arg0" instructions.

              			gen.Emit(OpCodes.Ldarg_0);
              			gen.Emit(OpCodes.Call, methodInfo);
              			gen.Emit(OpCodes.Ldarg_0);
              			gen.Emit(OpCodes.Call, methodInfo);
              

              I was trying to call the same method twice in your example. I've already found two bugs in my IL generation methods thanks to you. Here's the problem showing the key to my initial idea:

              	public class Program
              	{
              		delegate void MyDelegate();
              		public void TestMethod() { Console.WriteLine("Hello"); }
              		public void TestMethod2() { Console.WriteLine("hey"); }
              		public static void Main()
              		{
              			Program p = new Program();
              			MethodInfo methodInfo = p.GetType().GetMethod("TestMethod");
              			MethodInfo methodInfo2 = p.GetType().GetMethod("TestMethod2");
              
              			DynamicMethod dynMethod = new DynamicMethod("DynTestMethod", 
                                          null, null, typeof(Program));
              
              			ILGenerator gen = dynMethod.GetILGenerator();
              
              			gen.Emit(OpCodes.Ldarg_0);
              			gen.Emit(OpCodes.Call, methodInfo);
              
              			//IL instruction missing here
              			gen.Emit(OpCodes.Call, methodInfo2); //Most likely to produce the exception.
              
              			gen.Emit(OpCodes.Ret);
              
              			MyDelegate d = (MyDelegate)dynMethod.CreateDelegate(typeof(MyDelegate));
              			d.Invoke();
              			Console.ReadLine();
              
              		}
              	}
              

              The program gives an "InvalidProgramException" as expected. I wonder if there's a way to make that second Call instruction work. And others, if need be. Many thanks again for your help and sorry for the delay of this reply. Roberto Edit: here's another pseudo-msil dump of what I'm trying to get to run:

              .method void ManagedProcessInput 
              {
              	ldarg_0
              	call void UserInterface.ProcessInput()
              	call void UserInterfaceEditor.ProcessInput()
              	ret
              }
              

              Note: the methods stored in the MethodInfos are not static. Moreover, they are implementations of an interface.

              interface IMyInterface
              {
                 void Run();
              }
              
              class MyObject : IMyInterface
              {
                 [ctor / dtor]
                 public void Run()
                 {
                    [impl. here]
                 }
              }
              

              -- modified at 20:04 Saturday 13th January, 2007

              S Offline
              S Offline
              S Senthil Kumar
              wrote on last edited by
              #6

              I can't believe I missed it earlier, but the source of your problem is that the dynamically generated method is added as a static method. Being a static method, it does not have a this parameter, so a valid object reference needs to be passed. In my sample code, that would mean that MyDelegate would be modified like this

              delegate void MyDelegate(Program p);

              . The dynamic method's constructor would look like this

              DynamicMethod dynMethod = new DynamicMethod("DynTestMethod", null, new Type[] { typeof(Program) }, typeof(Program)); // Notice typeof(Program) added to the list of parameter types

              and the dynamic method invocation would look like this

              d.Invoke(p); // p is an instance of Program

              At the C# level, the generated method would look like this

              class Program
              {
              ...
              static void DynMethod(Program p)
              {
              p.TestMethod();
              p.TestMethod2();
              }
              }

              As you can see, earlier, there was no parameter being passed to the static method at all, which resulted in the weird exception you got. In your case, the simplest way would be to make m_MSILMethod accept parameters for all types on which methods would be invoked in its body. 1. In the constructor of the dynamic methods, you would need to provide all the types whose methods would be invoked (all elements in the m_TypeExecutionOrder array?) 2. The m_ILGenerator.Emit(OpCodes.LdArg_0) would obviously need to be modified to point to the correct parameter type. Something like this should work fine

              DynamicMethod m_MSILMethod;
              ILGenerator m_ILGenerator;

              foreach (string m_InterfaceMethod in m_InterfaceMethods)
              {

              [...]

              m_MSILMethod = new DynamicMethod(String.Format("Managed{0}", m_InterfaceMethod), null, m_TypeExecutionOrder.ToArray(), typeof(MyManager)); //assuming m_TypeExecutionOrder is List<Type>

              m_ILGenerator = m_MSILMethod.GetILGenerator();

              int index = 0;

              foreach (Type m_Type in m_TypeExecutionOrder)
              {

                foreach (MethodInfo m\_Method in m\_Methods\[m\_Type\])
                {
              
                   if (m\_Method.Name == m\_InterfaceMethod)
                   {
                      m\_ILGenerator.Emit(OpCodes.Ldarg, index); // note the dynamic changing of index according to the type
                      m\_ILGenerator.Emit(OpCodes.Call, m\_Method); // the actual call to the method
                   }
              
                }
              
                index++
              

              }

              m_ILGenerator.Emit(OpCodes.Ret);

              // Once the delegate is created, Emit() won't add more instructions, so the DynamicMethod is "done".
              m_MSILMethods.Add(m_InterfaceMe

              R 1 Reply Last reply
              0
              • S S Senthil Kumar

                I can't believe I missed it earlier, but the source of your problem is that the dynamically generated method is added as a static method. Being a static method, it does not have a this parameter, so a valid object reference needs to be passed. In my sample code, that would mean that MyDelegate would be modified like this

                delegate void MyDelegate(Program p);

                . The dynamic method's constructor would look like this

                DynamicMethod dynMethod = new DynamicMethod("DynTestMethod", null, new Type[] { typeof(Program) }, typeof(Program)); // Notice typeof(Program) added to the list of parameter types

                and the dynamic method invocation would look like this

                d.Invoke(p); // p is an instance of Program

                At the C# level, the generated method would look like this

                class Program
                {
                ...
                static void DynMethod(Program p)
                {
                p.TestMethod();
                p.TestMethod2();
                }
                }

                As you can see, earlier, there was no parameter being passed to the static method at all, which resulted in the weird exception you got. In your case, the simplest way would be to make m_MSILMethod accept parameters for all types on which methods would be invoked in its body. 1. In the constructor of the dynamic methods, you would need to provide all the types whose methods would be invoked (all elements in the m_TypeExecutionOrder array?) 2. The m_ILGenerator.Emit(OpCodes.LdArg_0) would obviously need to be modified to point to the correct parameter type. Something like this should work fine

                DynamicMethod m_MSILMethod;
                ILGenerator m_ILGenerator;

                foreach (string m_InterfaceMethod in m_InterfaceMethods)
                {

                [...]

                m_MSILMethod = new DynamicMethod(String.Format("Managed{0}", m_InterfaceMethod), null, m_TypeExecutionOrder.ToArray(), typeof(MyManager)); //assuming m_TypeExecutionOrder is List<Type>

                m_ILGenerator = m_MSILMethod.GetILGenerator();

                int index = 0;

                foreach (Type m_Type in m_TypeExecutionOrder)
                {

                  foreach (MethodInfo m\_Method in m\_Methods\[m\_Type\])
                  {
                
                     if (m\_Method.Name == m\_InterfaceMethod)
                     {
                        m\_ILGenerator.Emit(OpCodes.Ldarg, index); // note the dynamic changing of index according to the type
                        m\_ILGenerator.Emit(OpCodes.Call, m\_Method); // the actual call to the method
                     }
                
                  }
                
                  index++
                

                }

                m_ILGenerator.Emit(OpCodes.Ret);

                // Once the delegate is created, Emit() won't add more instructions, so the DynamicMethod is "done".
                m_MSILMethods.Add(m_InterfaceMe

                R Offline
                R Offline
                rcollina
                wrote on last edited by
                #7

                I am going to implement this and post my results in a post edit. :) I am really grateful for the help you've given so far. Best regards, Roberto -- modified at 20:01 Monday 15th January, 2007

                R 1 Reply Last reply
                0
                • R rcollina

                  I am going to implement this and post my results in a post edit. :) I am really grateful for the help you've given so far. Best regards, Roberto -- modified at 20:01 Monday 15th January, 2007

                  R Offline
                  R Offline
                  rcollina
                  wrote on last edited by
                  #8

                  Here's what I've done after your post. Sadly, there's still a bothering issue.

                    delegate void PlugInMethodDelegate(object[] Instances);
                  
                                   /* ... */
                  
                          m_MSILMethod = /* The dynamic method is here  */
                                 new DynamicMethod(String.Format("Managed{0}", m_InterfaceMethod),
                                      null, m_Params.ToArray(), typeof(PlugInManager));
                  
                  
                  	//Gives this error: Error binding to target method.
                          PlugInMethodDelegate m_Delegate = (PlugInMethodDelegate)m_MSILMethod.CreateDelegate
                                                                           (typeof(PlugInMethodDelegate));
                  

                  I cannot understand why the CreateDelegate method gives back an error - since the argument is just an object array, after all. Or there's something am I missing again?

                  PlugInManager: [ERROR] CreateMSILMethods(): Error binding to target method.
                  at System.Delegate.CreateDelegate(Type type, Object target, RuntimeMethodHandle method)
                  at System.Reflection.Emit.DynamicMethod.CreateDelegate(Type delegateType)
                  at Dreams.PlugInManager.CreateMSILMethodsLookup() in C:\xxxx.cs:line 1280

                      List< Type > m_Params;
                  

                  Here's the pseudo-msil dump:

                  .method void ManagedPreRender(UserInterface, UserInterfaceEditor) 
                  {
                  	ldarg 0		// param "UserInterface"
                  	call void UserInterface::PreRender()
                  
                  	ldarg 1		// param "UserInterfaceEditor"
                  	call void UserInterfaceEditor::PreRender()
                  
                  	ret
                  }
                  

                  Better than before, I hope. Many thanks again.

                  R 1 Reply Last reply
                  0
                  • R rcollina

                    Here's what I've done after your post. Sadly, there's still a bothering issue.

                      delegate void PlugInMethodDelegate(object[] Instances);
                    
                                     /* ... */
                    
                            m_MSILMethod = /* The dynamic method is here  */
                                   new DynamicMethod(String.Format("Managed{0}", m_InterfaceMethod),
                                        null, m_Params.ToArray(), typeof(PlugInManager));
                    
                    
                    	//Gives this error: Error binding to target method.
                            PlugInMethodDelegate m_Delegate = (PlugInMethodDelegate)m_MSILMethod.CreateDelegate
                                                                             (typeof(PlugInMethodDelegate));
                    

                    I cannot understand why the CreateDelegate method gives back an error - since the argument is just an object array, after all. Or there's something am I missing again?

                    PlugInManager: [ERROR] CreateMSILMethods(): Error binding to target method.
                    at System.Delegate.CreateDelegate(Type type, Object target, RuntimeMethodHandle method)
                    at System.Reflection.Emit.DynamicMethod.CreateDelegate(Type delegateType)
                    at Dreams.PlugInManager.CreateMSILMethodsLookup() in C:\xxxx.cs:line 1280

                        List< Type > m_Params;
                    

                    Here's the pseudo-msil dump:

                    .method void ManagedPreRender(UserInterface, UserInterfaceEditor) 
                    {
                    	ldarg 0		// param "UserInterface"
                    	call void UserInterface::PreRender()
                    
                    	ldarg 1		// param "UserInterfaceEditor"
                    	call void UserInterfaceEditor::PreRender()
                    
                    	ret
                    }
                    

                    Better than before, I hope. Many thanks again.

                    R Offline
                    R Offline
                    rcollina
                    wrote on last edited by
                    #9

                    I think I might be able to figure out this on my own. Thanks for the help so far! r.

                    S 1 Reply Last reply
                    0
                    • R rcollina

                      I think I might be able to figure out this on my own. Thanks for the help so far! r.

                      S Offline
                      S Offline
                      S Senthil Kumar
                      wrote on last edited by
                      #10

                      I don't think object[] will do. Having an object array as parameter is different from having a list of parameters. You should either modify the delegate to take the list of objects as a parameter, or modify the dynamically generated method to take an object array as a parameter and then read objects off the array, cast them (but you wouldn't know the type, so this will require additional parameters to the method) and call methods on the objects. I think the first approach i.e modifying the delegate signature would be the easiest to implement.

                      Regards Senthil [MVP - Visual C#] _____________________________ My Blog | My Articles | WinMacro

                      R 1 Reply Last reply
                      0
                      • S S Senthil Kumar

                        I don't think object[] will do. Having an object array as parameter is different from having a list of parameters. You should either modify the delegate to take the list of objects as a parameter, or modify the dynamically generated method to take an object array as a parameter and then read objects off the array, cast them (but you wouldn't know the type, so this will require additional parameters to the method) and call methods on the objects. I think the first approach i.e modifying the delegate signature would be the easiest to implement.

                        Regards Senthil [MVP - Visual C#] _____________________________ My Blog | My Articles | WinMacro

                        R Offline
                        R Offline
                        rcollina
                        wrote on last edited by
                        #11

                        I managed to make it work with a object[] argument. Thanks for your support so far, it's been very precious. Regards, Roberto

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups