私がやりたいのは、C#メソッドが呼び出されたときの実行方法を変更して、次のようなものを書けるようにすることです。
[Distributed]
public DTask<bool> Solve(int n, DEvent<bool> callback)
{
for (int m = 2; m < n - 1; m += 1)
if (m % n == 0)
return false;
return true;
}
実行時に、Distributed属性を持つメソッド(既に実行可能)を分析し、関数の本体が実行される前と関数が戻った後にコードを挿入できるようにする必要があります。さらに重要なことに、Solveが呼び出されるコードを変更することなく、または関数の開始時に(コンパイル時に、実行時に実行することが目的です)コードを変更せずにそれを実行できるようにする必要があります。
現時点で私はこのコードを試してみました(tはSolveが格納されている型であり、mはSolveのMethodInfoであると想定しています)。
private void WrapMethod(Type t, MethodInfo m)
{
// Generate ILasm for delegate.
byte[] il = typeof(Dpm).GetMethod("ReplacedSolve").GetMethodBody().GetILAsByteArray();
// Pin the bytes in the garbage collection.
GCHandle h = GCHandle.Alloc((object)il, GCHandleType.Pinned);
IntPtr addr = h.AddrOfPinnedObject();
int size = il.Length;
// Swap the method.
MethodRental.SwapMethodBody(t, m.MetadataToken, addr, size, MethodRental.JitImmediate);
}
public DTask<bool> ReplacedSolve(int n, DEvent<bool> callback)
{
Console.WriteLine("This was executed instead!");
return true;
}
ただし、MethodRental.SwapMethodBodyは動的モジュールでのみ機能します。すでにコンパイルされ、アセンブリに格納されているものではありません。
したがって、読み込まれて実行中のアセンブリに既に格納されているメソッドで SwapMethodBodyを効果的に実行する方法を探しています。
メソッドを動的モジュールに完全にコピーする必要がある場合は問題ありませんが、この場合、IL全体にコピーする方法を見つけ、Solve()へのすべての呼び出しを更新して、新しいコピーを指します。