DynamicMethod - 公共语言运行库检测到无效程序

时间:2016-12-20 14:02:03

标签: c# invoke dynamicmethod opcodes

所以我尝试使用ilgenerator通过dynamicmethod从外部DLL调用方法。

delegate void Write(string text);
static void Main(string[] args)
{
    byte[] bytes = File.ReadAllBytes(@"externmethod.dll");
    var assembly = Assembly.Load(bytes);
    var method = assembly.GetTypes()[0].GetMethod("Write");
    var dynamicMethod = new DynamicMethod("Write", typeof(void), new Type[] { typeof(string) });
    var ilGenerator = dynamicMethod.GetILGenerator();
    ilGenerator.EmitCall(OpCodes.Call, method, null);
    var delegateVoid = dynamicMethod.CreateDelegate(typeof(Write)) as Write;
    delegateVoid("test");
    Console.ReadLine();
}

和DLL代码:

using System;
class program
{
    public static void Write(string text)
    {
        Console.WriteLine(text);
    }
}

但是我收到了这个奇怪的错误:

  

未处理的类型' System.InvalidProgramException'发生在test.exe中   附加信息:公共语言运行时检测到无效程序。

我不知道我做错了什么?

1 个答案:

答案 0 :(得分:0)

您的委托delegate void Write(string text);接受字符串作为参数,因此您需要在发出call之前执行此操作:

ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldstr, "this is test");

你必须在方法结束时返回所以你需要这样做:

ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ret);

完整代码:

var method = assembly.GetTypes()[0].GetMethod("Write");
var dynamicMethod = new DynamicMethod("Write", typeof(void), new Type[] { typeof(string) });
var ilGenerator = dynamicMethod.GetILGenerator();
ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldstr, "this is test");
ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, method);
ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ret);
var delegateVoid = dynamicMethod.CreateDelegate(typeof(Write)) as Write;
delegateVoid("test");

更新:我注意到您要将参数发送到方法,而不是

ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldstr, "this is test");

写这个

ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);

然后您在此处发送的内容delegateVoid("test");将打印出来。

关于访问限制,如果您无法公开Program课程,则可以定义DynamicMethod这样的内容以获取访问权限:

var dynamicMethod = new DynamicMethod("Write", typeof(void), new[] { typeof(string) }, assembly.GetTypes()[0]);