オブジェクト上で遅延バインディング メソッドを呼び出し、戻り値を評価スタックにプッシュします。
Public Shared ReadOnly Callvirt As OpCode
[C#]
public static readonly OpCode Callvirt;
[C++]
public: static OpCode Callvirt;
[JScript]
public static var Callvirt : OpCode;
解説
命令の 16 進数の形式、MSIL (Microsoft Intermediate Language) アセンブリ形式、および簡単な説明の一覧を次の表に示します。
形式 | アセンブリ形式 | 説明 |
---|---|---|
6F < T > | callvirt method | obj と関連付けられた特定のメソッドを呼び出します。 |
スタックの遷移動作を順番に示すと、次のようになります。
- オブジェクト参照 obj がスタックにプッシュされます。
- メソッド引数の arg1 から argN までがスタックにプッシュされます。
- メソッド引数の arg1 から argN まで、およびオブジェクト参照 obj が、スタックからポップされます。メソッド呼び出しは、これらの引数を使用して実行され、メソッド メタデータ トークンによって参照される obj 内のメソッドに制御が転送されます。完了すると、呼び出し先メソッドによって戻り値が生成され、呼び出し元へ送られます。
- 戻り値がスタックにプッシュされます。
callvirt 命令は、オブジェクト上で遅延バインディング メソッドを呼び出します。つまり、メソッドの選択は、メソッド ポインタで参照できるコンパイル時クラスではなく、 obj のランタイム型に基づいて行われます。 Callvirt を使用して、仮想メソッドとインスタンス メソッドの両方を呼び出すことができます。 callvirt 命令の直前に tail (Tailcall) プリフィックスを置くことによって、制御を転送する前に現在のスタック フレームを解放するように指定できます。呼び出しによって、元のメソッドより信頼性の高いメソッドに制御が転送される場合、スタック フレームは解放されません。
メソッド メタデータ トークンは、呼び出すメソッドの名前、クラス、およびシグネチャを提供します。 obj に関連付けられているクラスは、obj がインスタンスであるクラスです。指定したメソッド名とシグネチャに一致する非静的メソッドをクラスが定義している場合は、このメソッドが呼び出されます。それ以外の場合は、このクラスの基本クラス チェインのすべてのクラスが順番にチェックされます。メソッドが見つからない場合は、エラーとなります。
メソッドを呼び出す前に、 Callvirt がオブジェクトおよび関連付けられている引数を評価スタックからポップします。メソッドに戻り値がある場合は、メソッドの完了時にスタックに戻り値がプッシュされます。呼び出し先側では、 obj パラメータが引数 0 としてアクセスされ、 arg1 が引数 1 としてアクセスされ、それ以降も同様にアクセスされます。
引数は、スタック上に左から右に配置されます。つまり、まず最初の引数が計算されてスタックに配置され、次に 2 番目の引数、その次に 3 番目の引数が同様に配置され、最終的に必要なすべての引数が降順でスタックに配置されます。インスタンス参照 obj (callvirt の場合は常に必要) は、ユーザーが参照できる任意の引数の前に、プッシュされる必要があります。(メタデータ トークンで送られる) シグネチャは、このポインタに対するパラメータ リストにエントリを格納する必要はありません。
Call 命令を使用して仮想メソッドを呼び出すこともできます。
obj と関連付けられたクラス内またはその基本クラス内で、指定した名前とシグネチャを持つ非静的メソッドが見つからない場合は、 MissingMethodException がスローされます。これは、通常、実行時ではなく、MSIL (Microsoft Intermediate Language) 命令がネイティブ コードに変換されるときに検出されます。
obj が null の場合は、 NullReferenceException がスローされます。
システム セキュリティが呼び出し元に対して呼び出すメソッドへのアクセスを許可していない場合は、 SecurityException がスローされます。セキュリティ チェックは、実行時ではなく、CIL がネイティブ コードに変換されるときに発生する場合があります。
callvirt オペコードを使用できる Emit コンストラクタ オーバーロードを次に示します。
- ILGenerator.Emit(OpCode, MethodInfo)
- ILGenerator.EmitCall(OpCode, MethodInfo, Type[])
必要条件
プラットフォーム: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 ファミリ