因此,我尝试通过使用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);
}
}
但是我遇到了一个奇怪的错误:
在test.exe
其他信息:常见语言运行时检测到无效的程序。
我不知道我在做什么错?
您的委托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");
Update :我注意到您要将参数发送到方法,而不是
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]);