是否可以调用OpCodes.Jmp将控制转移到驻留在不同程序集上的方法?

Ric*_*osa 3 c# reflection.emit

驻留在AssemblyA中的Method1可以向驻留在AssemblyB中的Method1发出OpCodes.Jmp吗?两种方法都具有相同的确切签名

我似乎无法使这项工作,总是得到System.InvalidProgramException:公共语言运行时检测到一个无效的程序.

如果重定向位于同一个程序集中,则可以正常工作.

如果可能,请使用Reflection.Emit提供示例.

Lua*_*aan 5

你一定错过了什么.两种方法都是静态的吗 他们有相同的召集惯例吗?

以下代码不会重现您的问题:

static void Main(string[] args)
{
    var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly
                    (new AssemblyName("TestAssembly"), AssemblyBuilderAccess.Run);
    var module = assembly.DefineDynamicModule("Main");
    var type = module.DefineType("Test");

    var method = type.DefineMethod
                  (
                    "Test", MethodAttributes.Public | MethodAttributes.Static, 
                    typeof(int), new[] { typeof(string) }
                  );
    var gen = method.GetILGenerator();
    gen.Emit(OpCodes.Jmp, typeof(Class1).GetMethod("Test"));

    var obj = Activator.CreateInstance(type.CreateType());

    var func = (Func<string, int>)
                obj.GetType().GetMethod("Test").CreateDelegate(typeof(Func<string, int>));
    var result = func("Banana");

    Console.WriteLine(result);
    Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)

在不同的集会中,Test班级:

public static class Class1
{
    public static int Test(string hi)
    {
        return 42;
    }
}
Run Code Online (Sandbox Code Playgroud)

你确定你没有违反任何限制吗?

  • 执行此指令时,评估堆栈必须为空.
  • 目标地址的调用约定,参数的数量和类型必须与当前方法的参数匹配.
  • jmp指令不能用于将控制转移到try,filter,catch或finally块之外.

  • @RicardoBarbosa我能想到的最好的是`DynamicMethod` - 这就是`LambdaExpression.Compile`所使用的.但是,如果您要将其作为委托调用(仅在此示例中),这才有意义.只需执行`new DynamicMethod("Test",typeof(int),new [] {typeof(string)})`,填入IL,然后填写`.CreateDelegate(typeof(Func <string,int>))`. (2认同)