pin_ptr (C++/CLI)
共通言語ランタイムでのみ使用される 固定ポインターを宣言します。
すべてのランタイム
(すべてのランタイムに適用するこの言語機能の解説はありません)。
ランタイム ウィンドウ
(この機能は、言語ランタイム ウィンドウでサポートされていません)。
共通言語ランタイム
固定ポインターが 指す文字ガベージコレクション ヒープ処理を続行することを防ぐ内部オブジェクトはへのポインターです。つまり、固定ポインターの値は、共通言語ランタイムに変更されません。これは、アドレスがアンマネージ関数の呼び出しの解決時に予期せず変更しないように、アンマネージ関数にマネージ クラスのアドレスを渡す場合に必要です。
構文
[cli::]pin_ptr<cv_qualifier type> var = &initializer;
パラメーター
cv_qualifier
const か volatile の修飾子。既定では、固定ポインターは、 volatileです。このエラーは、重複固定ポインター volatileを宣言するには異なります。type
initializer の型。var
pin_ptr 変数の名前。初期化子
マネージ配列の参照型、要素、または他のメンバー、ネイティブ ポインターに割り当てることができるオブジェクト。
解説
pin_ptr は、ネイティブ ポインターの機能のスーパーセットを表します。したがって、ネイティブ ポインターに割り当てることができるものも pin_ptrに割り当てることができます。内部ポインターが比較やポインター演算を含むネイティブ ポインターと操作のセットを実行することができます。
共通言語ランタイムがガベージ コレクション中に移動するマネージ クラスのオブジェクトまたはサブオブジェクトに固定できます。その主な用途は、アンマネージ関数の呼び出しの実パラメーターとしてマネージ データへのポインターを渡すことです。コレクション サイクル中に、ランタイムは固定ポインターのために作成されたメタデータを検査し、をポイントする項目を移動しません。
オブジェクトを固定して調整、値フィールドを固定; つまり、プリミティブまたは値型のフィールド。ただし、追跡ハンドル (%)によって宣言されたフィールドは固定する合わせません。
マネージ オブジェクトで定義されているサブオブジェクトを固定すると、全体のオブジェクトを固定する効果があります。
固定ポインターが新しい値を指すように割り当て直されれば、が指す前のインスタンスは、固定されたとは見なされません。
オブジェクトは、のみ情報への pin_ptr ポイントの固定。です。へのオブジェクトは、固定ポインターがスコープ外に出る固定する合わせませんの場合、またはがに設定されていません。pin_ptr がスコープ外になると、固定されたオブジェクトは、ガベージ コレクターによってヒープに移動することができます。まだオブジェクトをポイントするネイティブ ポインターでもなく更新およびそれらの 1 回復不可能な例外を発生させる可能性があります逆参照します。
オブジェクトへの固定ポインターの位置 (すべての固定ポインターは、スコープの外に出ますか、他のオブジェクトを指すように再割り当てされる場合、または です。を割り当てる)、固定オブジェクトに合わせないことが保証されます。
固定ポインターは、マネージ型の参照のハンドルに、値型または化された型のハンドル、メンバー、またはマネージ配列の要素指定できます。これは、参照型をポイントすることはできません。
ネイティブ オブジェクトの原因を指す pin_ptr のアドレスを受け取ることの動作は、定義されていません。
固定ポインターは、スタックの非静的なローカル変数としてしか宣言できません。
固定ポインターは次のように使用できません:
関数パラメーター
関数の戻り値の型
クラスのメンバー
キャストを対象の型。
pin_ptr は cli の名前空間にあります。詳細については、「プラットフォーム、既定、および cli 名前空間 (C++ コンポーネント拡張)」を参照してください。
内部ポインターに関する詳細については、 interior_ptr (C++/CLI)を参照してください。
ポインターを固定する方法の詳細については、 方法 : ポインターと配列を固定する と 方法 : 固定ポインターと値型を宣言するを参照してください。
要件
コンパイラ オプション: /clr
例
例
次の例では、配列の先頭の要素の位置を制限するに pin_ptr を使用します。
// pin_ptr_1.cpp
// compile with: /clr
using namespace System;
#define SIZE 10
#pragma unmanaged
// native function that initializes an array
void native_function(int* p) {
for(int i = 0 ; i < 10 ; i++)
p[i] = i;
}
#pragma managed
public ref class A {
private:
array<int>^ arr; // CLR integer array
public:
A() {
arr = gcnew array<int>(SIZE);
}
void load() {
pin_ptr<int> p = &arr[0]; // pin pointer to first element in arr
int* np = p; // pointer to the first element in arr
native_function(np); // pass pointer to native function
}
int sum() {
int total = 0;
for (int i = 0 ; i < SIZE ; i++)
total += arr[i];
return total;
}
};
int main() {
A^ a = gcnew A;
a->load(); // initialize managed array using the native function
Console::WriteLine(a->sum());
}
出力
例
次の例は、内部ポインターが固定ポインターに変換できること、またオペランドがマネージ ヒープにある場合&演算子 ()のアドレスの戻り値の型が内部ポインターであることを示します。
// pin_ptr_2.cpp
// compile with: /clr
using namespace System;
ref struct G {
G() : i(1) {}
int i;
};
ref struct H {
H() : j(2) {}
int j;
};
int main() {
G ^ g = gcnew G; // g is a whole reference object pointer
H ^ h = gcnew H;
interior_ptr<int> l = &(g->i); // l is interior pointer
pin_ptr<int> k = &(h->j); // k is a pinning interior pointer
k = l; // ok
Console::WriteLine(*k);
};
出力
例
次の例は、固定ポインターを別の型にキャストできることを示しています。
// pin_ptr_3.cpp
// compile with: /clr
using namespace System;
ref class ManagedType {
public:
int i;
};
int main() {
ManagedType ^mt = gcnew ManagedType;
pin_ptr< int > pt = &mt->i;
*pt = 8;
Console::WriteLine(mt->i);
char *pc = ( char* ) pt;
*pc = 255;
Console::WriteLine(mt->i);
}
出力