1.本地类中包含托管类成员变量的情况
1 #include<vcclr.h> // 必须包含vcclr.h头文件 2 3 //传入 4 5 A^ a = gcnew A(); 6 7 gcroot<A^> *pA = new gcroot<A^>(); 8 9 *pA = a; 10 11 void *ptr = pA; 12 13 B *b = new B(pA); //c++类 14 15 //还原 16 17 gcroot<A^> * m_pA = (gcroot<A^> *)pA; 18 19 (*m_pA)->FuncA(); //可调用A类接口;
2.pin_ptr是防止您的对象移动将在垃圾回收堆的内部指针. 也就是说钉住指针的值不是由公共语言运行时更改. 当向非托管函数传递托管类的地址时,这很有用,因为在解析非托管函数调用的过程中,该地址不会意外更改.
pin_ptr无法使用情况(在pin_ptr的生命周期内有效):
-
-
函数参数
-
作为函数的返回类型。
-
类成员的声明
-
目标的类型约束。
-
pin_ptr 数组的第一个元素的位置
1 // pin_ptr_1.cpp 2 // compile with: /clr 3 using namespace System; 4 #define SIZE 10 5 6 #pragma unmanaged 7 // native function that initializes an array 8 void native_function(int* p) { 9 for(int i = 0 ; i < 10 ; i++) 10 p[i] = i; 11 } 12 #pragma managed 13 14 public ref class A { 15 private: 16 array<int>^ arr; // CLR integer array 17 18 public: 19 A() { 20 arr = gcnew array<int>(SIZE); 21 } 22 23 void load() { 24 pin_ptr<int> p = &arr[0]; // pin pointer to first element in arr 25 int* np = p; // pointer to the first element in arr 26 native_function(np); // pass pointer to native function 27 } 28 29 int sum() { 30 int total = 0; 31 for (int i = 0 ; i < SIZE ; i++) 32 total += arr[i]; 33 return total; 34 } 35 }; 36 37 int main() { 38 A^ a = gcnew A; 39 a->load(); // initialize managed array using the native function 40 Console::WriteLine(a->sum()); 41 }
内部指针转换为钉住的指针,并且,类型为返回 address-of 运算符 (&) 是内部指针,当操作数在托管堆时
1 // pin_ptr_2.cpp 2 // compile with: /clr 3 using namespace System; 4 5 ref struct G { 6 G() : i(1) {} 7 int i; 8 }; 9 10 ref struct H { 11 H() : j(2) {} 12 int j; 13 }; 14 15 int main() { 16 G ^ g = gcnew G; // g is a whole reference object pointer 17 H ^ h = gcnew H; 18 19 interior_ptr<int> l = &(g->i); // l is interior pointer 20 21 pin_ptr<int> k = &(h->j); // k is a pinning interior pointer 22 23 k = l; // ok 24 Console::WriteLine(*k); 25 };
钉住的指针转换为另一种类型
1 // pin_ptr_3.cpp 2 // compile with: /clr 3 using namespace System; 4 5 ref class ManagedType { 6 public: 7 int i; 8 }; 9 10 int main() { 11 ManagedType ^mt = gcnew ManagedType; 12 pin_ptr< int > pt = &mt->i; 13 *pt = 8; 14 Console::WriteLine(mt->i); 15 16 char *pc = ( char* ) pt; 17 *pc = 255; 18 Console::WriteLine(mt->i); 19 }
3.char * to array<unsigned char^>
1 #pragma unmanaged 2 3 void work_with_native_buffer(char* pBuffer, size_t size) { 4 // Do your unmanaged stuff here 5 } 6 7 #pragma managed 8 9 ref class Test { 10 public: 11 void DoNativeStuff() { 12 if (_buffer == nullptr) 13 _buffer = gcnew array<unsigned char>(256); 14 15 pin_ptr<int> pinnedBuffer = &_buffer[0]; 16 char* pBuffer = pinnedBuffer; 17 work_with_native_buffer(pBuffer, _buffer->Length); 18 } 19 20 void SendData(Stream^ stream) { 21 Debug.Assert(_buffer != nullptr); 22 23 stream->Write(_buffer, 0, _buffer->Length); 24 } 25 26 private: 27 array<unsigned char>^ _buffer; 28 };