方向属性
すべてのメソッド パラメーターを、InAttribute 属性、OutAttribute 属性、またはその両方の設定に関連付けることができます。 マネージ メモリとアンマネージ メモリ間での実行時のマーシャリングを修正するには、デザイン時に方向属性を適用します。
InAttribute と OutAttribute は System.Runtime.InteropServices 名前空間にあり、その機能はインターフェイス定義言語 (IDL: Interface Definition Language) のインターフェイス属性である [in]、[out]、[in/out]、および [out, retval] と同じです。
メモ |
---|
マネージ メソッド シグネチャの戻り値は常にタイプ ライブラリ内の [out, retval] に割り当てられます。適用可能な等価の方向属性はありません。 |
方向属性は省略できます。 マーシャラーの既定の動作を変更する場合に、メソッド パラメーターに方向属性を適用します。 メソッド パラメーターから方向属性を省略した場合は、マーシャラーはパラメーターの型 (値または参照) および (存在する場合は) その修飾子に基づいて方向を決定します。
メソッド パラメーターの方向を修正できるようにするキーワードを提供する言語もあります。 Visual Basic 2005 および C# によって提供される方向関連のキーワードと、それに対応する IDL インターフェイス属性を次の表に示します。
Visual Basic 2005 |
C# |
IDL 属性 |
---|---|---|
ByVal |
対応する項目はありません。 |
[in] |
ByRef |
ref |
[in/out] |
対応する項目はありません。 |
out |
[out] |
パラメーター修飾子の ByRef、ref、および out を指定すると、メソッド引数は値渡しではなく参照渡しでマーシャリングされるようになります。 値渡しされるメソッド引数は、スタック上の値としてアンマネージ コードへとマーシャリングされます。参照渡しされるメソッド引数は、スタック上のポインターとしてマーシャリングされます。 パラメーター修飾子を伴う値型と参照型に対する既定のマーシャリングの動作を次の図に示します。
メソッド引数のアンマネージ コードへの既定のマーシャリング動作
既定ではパフォーマンス上の理由により、値渡しされる参照型 (クラス、配列、文字列、およびインターフェイス) は In パラメーターとしてマーシャリングされます。 これらの型に対する変更は、InAttribute と OutAttribute (または OutAttribute だけ) をメソッド パラメーターに適用しない限りは行われません。 StringBuilder クラスはこの規則の例外であり、In/Out パラメーターとしてマーシャリングされます。
相互運用マーシャラーは、方向属性に関して次の動作を保証します。
相互運用マーシャラーは、アンマネージ コードから渡された In パラメーターに対する書き込み操作は行いません。 したがって、アンマネージ コードは、読み込み専用のページへのポインター、または同時にアクセスされるデータへのポインターを安全に渡すことができます。
コピーしたオブジェクトに、BSTR などの割り当て済みオブジェクトが含まれる場合、マーシャラーは常に In/Out 設定によって要求されたとおりに、一連の割り当ておよび破棄を正確に実行します。
方向属性はコード内で正確に適用する必要があります。 マネージ コード内のパラメーターに対して InAttribute と OutAttribute を適切に適用することで、タイプ ライブラリ エクスポーター (Tlbexp.exe) がこれらのビットを使用して、対応するタイプ ライブラリ内で確実に In/Out ビットを設定するようになります。このことは、一部の配列やクラスなどの固定できる参照型を操作する場合には特に重要です。