pin_ptr (C++/CLI)
共通言語ランタイムでのみ使用される の固定ポインターを宣言します。
すべてのランタイム
(この言語機能にはランタイムに適用される特記事項がありません。)
Windows ランタイム
(この言語機能は、Windows ランタイムでサポートされていません)。
共通言語ランタイム
固定のポインターは ガベージ コレクトされたヒープを続行することを防ぐ指されたオブジェクトは内部ポインターです。 つまり、固定ポインターの値は、共通言語ランタイムによって変更されません。 これは、アドレスがアンマネージ関数の呼び出しを解決するときに予期せず変更しないようにアンマネージ関数にマネージ クラスのアドレスを渡すときに必要です。
構文
[cli::]pin_ptr<cv_qualifier type> var = &initializer;
パラメーター
cv_qualifier
const または volatile 修飾子。 既定では、固定ポインターの volatileです。 これは、エラーの詳細 volatile固定ポインターを宣言する場合、必須ではありません。type
initializer の型。var
pin_ptr 変数の名前。initializer
マネージ配列の参照型、要素、または他のメンバー、ネイティブ ポインターに割り当てることのできるオブジェクト。
解説
pin_ptr はネイティブ ポインター機構のスーパーセットを表します。 したがって、ネイティブ ポインターに割り当てることができるものも pin_ptrに割り当てることができます。 内部ポインターを比較およびポインター演算を含むネイティブ ポインターと操作のセットを実行することができます。
共通言語ランタイムがガベージ コレクション中に移動するマネージ クラスのオブジェクトまたはサブオブジェクトを固定することもできます。 次の主な用途は、アンマネージ関数の呼び出しに指定された実パラメーターとしてマネージ データへのポインターを渡すことです。 コレクション サイクルで、ランタイムは固定ポインターのために作成されたメタデータを検査し、を指す項目を移動しません。
オブジェクトを固定することも、値フィールドを固定します; つまり、プリミティブ型または値型のフィールド。 ただし、トラッキング ハンドル (%) で宣言されたフィールドが固定があります。
マネージ オブジェクトで定義されているサブオブジェクトを固定すると、オブジェクト全体を固定する効果があります。
固定ポインターの新しい値を指すように割り当て直されればが指す前のインスタンスは、ピン止めとは見なされません。
オブジェクトは pin_ptr が指す間だけ固定されます。 nullptrにオブジェクトは、固定のポインターがスコープの外に出る固定があります。か、設定されません。 pin_ptr がスコープ外になると、ピン止めオブジェクトはガベージ コレクターによってヒープに移動できます。 まだオブジェクトを指すポインターのネイティブでも、更新されなくし、その 1 回復不能な例外を発生させるできます。逆参照します。
固定ポインターのオブジェクト (すべての固定のポインターはスコープの for か、そのオブジェクトを指すように再割り当てまたは nullptrを割り当てた) 示されていない場合は、オブジェクトが固定できないことは保証されません。
固定のポインターはマネージ型参照のハンドルを、値型とボックス化された型のハンドル、メンバー、またはマネージ配列の要素を指定することもできます。 これは、参照型を指定することはできません。
ネイティブ オブジェクトの原因を指す 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);
};
出力
1
例
次の例では、固定ポインターの別の型にキャストすることを示します。
// 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);
}
出力
8