1

私はこの方法を持っています:

public int Test()
{
    ExternalClass cls = new ExternalClass();
    return cls.ExternalMethod();
}

次のように、タイプをパラメーターとして渡し、オブジェクトの直接作成を削除できるように、ILインジェクションを使用して変更する必要があります。

public int Test(ExternalClass cls)
{

    return cls.ExternalMethod();
}

<>。Parameters.Add( _ ___ )を使用して追加のパラメーターを追加し、新しいアセンブリを生成することができます。

問題は、新しいオブジェクトを作成するための命令を削除できないことです。以下は、それを削除するために使用した行です。

ILProcessor ilProcessor = <<MethodDefinition>>.Body.GetILProcessor();
ilProcessor.Remove(<<newobj instruction>>);

以下のように変更されたアセンブリメソッドを呼び出そうとすると、「共通言語ランタイムが無効なプログラムを検出しました」というエラーがスローされます。

ExternalClass ext = new ExternalClass();
int i = prg1.Test(ext);

私もメモリ割り当て関連のものを処理する必要があるかもしれないことを知っています。誰かがここで実装する追加の手順を提供できれば幸いです。

4

1 に答える 1

6

newobj命令を削除するだけでは不十分です。ランタイムが言ったように、あなたは無効なプログラムを残されています。元の方法がILにどのように変換されるかを大まかに示します。

public Int32 Test()
{
    .local ExternalClass 0;

    // ExternalClass cls = new ExternalClass();
    newobj class ExternalClass();
    stloc.0;

    // return cls.ExternalMethod();
    ldloc.0;
    callvirt Int32 class ExternalClass:ExternalMethod();
    ret;
}

newobj命令のみを削除すると、そのstloc命令はローカルに格納するスタックに何もありません。メソッドを次のように変換する必要があります。

public Int32 Test(ExternalClass cls)
{
    // return cls.ExternalMethod();
    ldarg.1;
    callvirt Int32 class ExternalClass:ExternalMethod();
    ret;
}

したがって、次の3つのことを行う必要があります。

  1. メソッドシグネチャに引数を追加し、
  2. 指示までのすべて削除しますldloc
  3. ldarg.1メソッドの先頭に命令を挿入します。

ExternalClassオプションで、ローカルを削除することもできます。(これはJITコンパイラーによって最適化されますが、ILイメージを肥大化させます。)

于 2013-01-02T18:55:39.487 に答える