2009-11-22 3 views
8

私は動的に生成されたメソッドから内部メソッドを呼び出そうとしています。 ilコードは単純です:ldarg_0、callvirt、ret。.NETの動的メソッドから内部メソッドを呼び出すことはできますか?

このメソッドを実行すると、内部メソッドが定義されている型をロードできないというTypeLoadExceptionが発生します。

私はそれを考えると、動的メソッドホストアセンブリは、メソッドの宣言型アセンブリの友人ではないため、論理的です。

しかし、私は、Delegate.CreateDelegateのように、まだ動的メソッドが動作することを期待しています。結局のところ、私は内部メソッドのMethodInfoを取得することができたので、権限の障壁が私の後ろにあります。

とにかく、「動的に生成されたメソッドから内部メソッドを呼び出すことはできますか?」という質問があります。

ありがとうございました。

EDIT:

:私はData.Stringインスタンスプロパティにアクセスするには、2つのオープン・インスタンスのデリゲートを作成するコードで

using System; 
using System.Linq.Expressions; 
using System.Reflection; 
using System.Reflection.Emit; 

namespace A 
{ 
    internal class Data 
    { 
    internal string String { get; set; } 
    } 

    public static class Program 
    { 
    public static void Main() 
    { 
     Expression<Func<Data, string>> expr = x => x.String; 
     var getterInfo = ((PropertyInfo)((MemberExpression)expr.Body).Member).GetGetMethod(true); 
     var getter1 = (Func<Data, string>)Delegate.CreateDelegate(typeof(Func<Data, string>), getterInfo); 
     var dm = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object) }); 
     var gen = dm.GetILGenerator(); 
     gen.Emit(OpCodes.Ldarg_0); 
     gen.Emit(OpCodes.Castclass, typeof(Data)); 
     gen.Emit(OpCodes.Callvirt, getterInfo); 
     gen.Emit(OpCodes.Ret); 
     var getter2 = (Func<object, object>)dm.CreateDelegate(typeof(Func<object, object>)); 

     var data = new Data() { String = "Hello" }; 
     var str1 = getter1(data); 
     var str2 = getter2(data); 
    } 
    } 
} 

:ここ

は、問題を実証する簡単なコードサンプルです

  • Delegate.CreateDelegateを使用する安全なgetter1
  • タイプuns AFE getter2 DynamicMethod

Delegate.CreateDelegateによって作成されたタイプセーフデリゲートが機能を使用して、DynamicMethod使用して1はTypeLoadExceptionで失敗しながら。

getterが作成されるコンテキストは一般的ではないため、型の安全なアプローチはしたくないことに注意してください。もちろん、私はこの問題を解決することができますが、問題は主体の問題です--Delegate.CreateDelegateが成功するところでDynamicMethodが失敗するのはなぜですか?

+0

TypeLoadExceptionは、アセンブリが見つかりません - 融合ログビューアとは何ですか? –

+0

融合ログは空です。アセンブリをロードするのに問題はありません。関連するすべてのアセンブリは、同じフォルダに配置されています。 – mark

+0

@JeremyMcGeeが正しいです。デバッグモード中にAppDomainでロードされたアセンブリのリストを取得し、そこでターゲットアセンブリをチェックします。また、あなたのコードをここに入れてチェックする方が良いでしょう。 –

答えて

6

可視性チェックをスキップすると機能します。

変更

var dm = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object) }, true); 

msdn参照してください。この行:(。特定のテーブル内のすべてのルールを持つ)

これはコンストラクタにDOCOからです。

restrictedSkipVisibilityタイプ:この制限のある動的 方法のMSILによってアクセスタイプとメンバー にJIT 可視性チェックをスキップする真 可能System.Boolean: はそれらを含むことアセンブリの 信頼レベルタイプとメンバは、 の動的メソッドを送信するコールスタックのレベル 以下である必要があります。それ以外の場合はfalseです。

+0

DynamicMethodは.net標準にはありません.Net標準でこれを行う方法はありますか? – trampster

関連する問題