1

私は専用のミニ コンパイラを作成しており、逆アセンブルされた CIL をよく見て、やり方を理解しています。しかし、逆アセンブルされたコードを Reflection.Emit 呼び出しに変換する方法が明確でないことがよくあります。この翻訳を行うための参照マニュアルまたはその他の情報源はありますか?

編集: はい、オペコードを ILGenerator にマッピングするのは非常に簡単です。私は .directives や属性のような他のすべてのものについて話しています。たとえば、次のようなものに相当する Reflection.Emit の書き方をどのように見つけますDictionary<TKey,TValue>か?

.class public auto ansi serializable beforefieldinit Dictionary<TKey, TValue>
    extends System.Object
    implements System.Collections.Generic.IDictionary`2<!TKey, !TValue>,
    System.Collections.Generic.ICollection`1<valuetype 
        System.Collections.Generic.KeyValuePair`2<!TKey, !TValue>>, 
    ...
{
    .custom instance void System.Diagnostics.DebuggerDisplayAttribute::
        .ctor(string) = { string('Count = {Count}') }

    .method public hidebysig newslot virtual final instance bool TryGetValue
        (!TKey key, [out] !TValue& 'value') cil managed
    {
        .maxstack 3
        .locals init ([0] int32 num)
        ...

または、「param」ディレクティブはどうですか?

// public static void SayHello(string s = "Hello World!")
.method public hidebysig static void SayHello([opt] string s) cil managed
{
    .param [1] = "Hello World!"
4

3 に答える 3

4

そのためには、BLToolkit の EmitHelper コンポーネントを使用ます。Reflection.Emit をラップする、IL コードに似た流暢な API を提供します。リンクされた記事から抽出された例:

EmitHelper emit = new AssemblyBuilderHelper("HelloWorld.dll")
    .DefineType  ("Hello", typeof(object), typeof(IHello))
    .DefineMethod(typeof(IHello).GetMethod("SayHello"))
    .Emitter;
emit
    // string.Format("Hello, {0}!", toWhom)
    //
    .ldstr   ("Hello, {0}!")
    .ldarg_1
    .call    (typeof(string), "Format", typeof(string), typeof(object))

    // Console.WriteLine("Hello, World!");
    //
    .call    (typeof(Console), "WriteLine", typeof(string))
    .ret();

Type type = emit.Method.Type.Create();
于 2010-06-16T06:40:24.253 に答える
1

誰も質問に答えることができなかったので、ilasm 構文と Reflection.Emit 呼び出しの関係を示すドキュメントは存在しないと結論付けました。

補足として、Reflection.Emit よりもRunSharpを使用して実行時にコードを作成する方が通常は優れていることがわかりました。時間ができたら、新しいバージョンのCecilを見つけようと思います。

于 2011-04-10T21:15:52.263 に答える
1

System.Collections.Generic.Dictionary<> クラスの IL を見ています。「Dictionary」クラス名は、ModuleBuilder.DefineType() に渡す文字列です。

.param 属性は、C# バージョン 4 または VB.NET で、既定値を持つパラメーターに対して生成されます。MethodBuilder.DefineParameter() から返される ParameterBuilder で設定します。SetConstant() メソッドを使用します。

于 2010-06-13T21:03:28.980 に答える