背景: ドメイン固有の CLI 実装に取り組んでいます。この実装では、Mono またはその一部に含まれる BCL を使用することを期待しています。Mono の他の部分は使用しません。CLR/VES 自体をゼロから実装します。現在、CLR 自体と BCL の間の「境界層」を調査しているので、CLR が BCL の期待どおりに動作することを確認できます。
Mono BCL のソース コードで、理解に苦しむ箇所に出くわしました。それはの実装にありSystem.Delegate
ます:
...
private object m_target;
...
public MethodInfo Method {
...
}
...
#if NET_2_0
public object DynamicInvoke (params object[] args)
#else
public object DynamicInvoke (object[] args)
#endif
{
return DynamicInvokeImpl (args);
}
protected virtual object DynamicInvokeImpl (object[] args)
{
if (Method == null) {
Type[] mtypes = new Type [args.Length];
for (int i = 0; i < args.Length; ++i) {
mtypes [i] = args [i].GetType ();
}
method_info = m_target.GetType ().GetMethod (data.method_name, mtypes);
}
#if NET_2_0
if ((m_target != null) && Method.IsStatic) {
// The delegate is bound to m_target
if (args != null) {
object[] newArgs = new object [args.Length + 1];
args.CopyTo (newArgs, 1);
newArgs [0] = m_target;
args = newArgs;
} else {
args = new object [] { m_target };
}
return Method.Invoke (null, args);
}
#endif
return Method.Invoke (m_target, args);
}
を見ていDynamicInvokeImpl
ます。最初のビットは明らかですMethodInfo
。呼び出された署名に基づいて を取得しています。
2回目以降はおかしくなる#if NET_2_0
。ターゲット オブジェクトが指定され、呼び出されるメソッドが staticの場合、引数に 'this' ポインターが追加されるようです。
この場合によっては変更された引数リストを に渡しますMethodInfo.Invoke
。このメソッドの MSDN ドキュメントを見てきましたが、インスタンスメソッドを呼び出す場合でも、'this' ポインターを含めることは想定されていないことは明らかです。
これは、Mono の内部の一部を呼び出しているわけSystem.Reflection.MethodInfo
ではないことに注意してください。
私は、CLR が非表示の引数 (通常は型ハンドル) をジェネリッククラスの静的メソッド呼び出しに挿入する必要があることを認識しています。ただし、1) これは「this」参照であり、型ハンドルではありません。2) コードは、ジェネリッククラスだけでなく、大規模にそれを行っているように見えます。3) そのようなことは、下位レベルではなく、下位レベルで行われます。MethodInfo.Invoke
!の呼び出し元
ここで何が起こっているのか手がかりはありますか?