2016-12-20 8 views
0

Поэтому я пытаюсь вызвать метод из внешней библиотеки DLL с помощью динамического метода, используя ilgenerator.DynamicMethod - время выполнения общего языка обнаруживает недопустимую программу

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

Но я получаю эту странную ошибку:

An unhandled exception of type 'System.InvalidProgramException' occurred in test.exe
Additional information: Common Language Runtime detected an invalid program.

И я не имею никакого понятия, что им делать неправильно ??

ответ

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"); 

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]); 
+0

Я попробовал ваш код, но это дает мне другую ошибку; –

+0

Errormessage: Дополнительная информация: Попытка метода «DynamicClass.Write (System.String)» для доступа к программе «program.Write (System.String)» не удалась. –

+1

@JustusBosschieter Это 'MethodAccessException'. Сделайте 'Program' class' public'. –

 Смежные вопросы

  • Нет связанных вопросов^_^