2016-12-20 103 views
0

したがって、ilgeneratorを使用して動的メソッドを使用してextern DLLからメソッドを呼び出しようとしました。 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.

そして、私が間違ってやって何イム任意の手掛かりを持っていません?

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

をそして、あなたはそれを行う必要があるので、あなたは、メソッドの最後に返す必要があります:あなたはcallを放出する前にこれを実行する必要があるので、パラメータとして文字列を受け入れる

答えて

0

デリゲートdelegate void Write(string text);

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

次にあなたがここにdelegateVoid("test");を送信すると、プリントアウトされます。この

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

を書きます。

そして、あなたはProgramクラスを公開することができない場合はアクセス制限について、あなたはアクセスを得るために、このようなあなたのDynamicMethodを定義することができます。

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

私はあなたのコードを試みたが、それは私に別のエラーが発生します。 –

+0

Errormessage:追加情報: 'program.Write(System.String)'メソッドにアクセスするための 'DynamicClass.Write(System.String)'メソッドによる試行が失敗しました。 –

+1

@JustusBosschieterこれは 'MethodAccessException'です。 'Program'クラスを' public'にします。 –

関連する問題