オブジェクト自身ではなく、その内部へのポインタを宣言できます。
cli::interior_ptr<cv_qualifier type> var = &initializer;interior_ptr | MSDN
ref class MyClass
{
public:
int a;
};
int main()
{
MyClass^ myClass = gcnew MyClass();
myClass->a = 1;
// int* p = &(myClass->a); // error C2440: '初期化中': 'cli::interior_ptr<int>' から 'int *' に変換できません。
interior_ptr<int> p = &(myClass->a);
(*p)++; // myClass->a は2となる
}
アンマネージド ポインタはガベージコレクションによってインスタンスのマネージド ヒープ上での位置が変更されると追跡できず、内部ポインタはそれを解決する仕組みです。
固定ポインタは、ガベージコレクションによってアドレスが変更されるのを防ぐ内部ポインタです。
[cli::]pin_ptr<cv_qualifier type> var = &initializer;pin_ptr (C++/CLI) | MSDN
これは次のように、アンマネージド ポインタを受け取る関数に、マネージド型のポインタを渡すような場合に利用できます。
void Increment(int* p)
{
(*p)++;
}
int main()
{
Int32 n1 = 10;
pin_ptr<Int32> p1 = &n1; // 値n1への参照をコピー
int* p = p1; // 固定ポインタのアドレスは、アンマネージド ポインタへコピーできる
Increment(p1);
// n1とp1は11になる
Int32^ n2 = gcnew Int32(10);
pin_ptr<Int32> p2 = &*n2; // 参照n2への参照をコピー
Increment(p2);
// *n2とp2は11になる
Int32 n = *n2; // 参照n2の値をnへコピー
pin_ptr<Int32> p3 = &n; // 値nへの参照をコピー
Increment(p3);
// *n2は11のまま、nとp3は12になる
return 0;
}
また「error C2664: '***': 引数 1 を 'cli::interior_ptr<type *>' から 'type **' へ変換できません。」としてエラーとなる場合も、
pin_ptr<type*> p = &a;
のように取得したポインタを渡すことで解決できます。c++ cli - Convert from C++/CLI pointer to native C++ pointer - Stack Overflow
pin_ptrで宣言されたオブジェクトのスコープが外れると、それが指し示すポインタの固定も解除されます。
オブジェクトを示さないオブジェクト ハンドル、内部ポインタまたはアンマネージド ポインタの値を表現できます。このキーワードはマネージドおよびアンマネージドの型に対して用いられますが、コンパイラはそれぞれ異なるコードを生成します。