可以操作码.Jmp将控制转移到驻留在不同程序集中的方法

本文关键字:程序 程序集 方法 集中 Jmp 操作码 控制 转移 | 更新日期: 2023-09-27 18:01:18

驻留在AssemblyA中的Method1可以发出操作码吗?跳转到驻留在AssemblyB中的Method1 ?两种方法都有相同的签名。

我似乎做不到这一点,总是得到系统。InvalidProgramException:公共语言运行库检测到一个无效程序。

如果重定向在同一个程序集中,它可以工作。

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

可以操作码.Jmp将控制转移到驻留在不同程序集中的方法

你一定错过了什么。这两个方法都是静态的吗?他们有相同的通话习惯吗?

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

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();
}

在另一个程序集中,Test类:

public static class Class1
{
    public static int Test(string hi)
    {
        return 42;
    }
}

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

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