interior_ptrはマネージヒープ上にあるvalue typeや基本型を指すためのポインタです。
以下のコードを考えます。
ref class R { public: Object o; int i; }; void set100(int* i) { *i = 100; } int main() { R^ r = gcnew R; set100(&r->i); }
このコードはset100()でエラーになります。マネージヒープ上にあるものはポインタで受け取ることはできません。マネージヒープ上のデータはいつ場所が変わるかわからないため、純粋なアドレスを保持するポインタではまずいのです。
そこで以下のようにして見ます。
ref class R { public: Object o; int i; }; void set100(int^ i) { i = 100; } int main() { R^ r = gcnew R; set100(r->i); }
こうするとset100()のところではr→iはボックス化されてしまい、100がセットされるのは、新しく作られたintインスタンスに対してです。このインスタンスはいずれ捨てられてしまいます。
そこでinterior_ptrを用いて以下のように書きます。
ref class R { public: Object o; int i; }; void set100(interior_ptr<int> i) { *i = 100; } int main() { R^ r = gcnew R; set100(&r->i); }
これでr→iを変更することができます。また普通のint*をset100()に渡すこともできます。
また、トラッキング参照を用いて以下のように書くこともできます。
ref class R { public: Object o; int i; }; void set100(int% i) { i = 100; } int main() { R^ r = gcnew R; set100(r->i); }
トラッキング参照も、普通のintを受け取ることができます。