0

因此,我尝试使用 ilgenerator 通过动态方法从外部 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);
    }
}

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

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

而且我不知道我做错了什么?

4

1 回答 1

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]);
于 2016-12-20T14:45:20.380 回答