How to: Hold Object Reference in Unmanaged Memory

 

For the latest documentation on Visual Studio 2017, see Visual Studio 2017 Documentation.

You can use gcroot.h, which wraps GCHandle, to hold a CLR object reference in unmanaged memory. Alternatively, you can use GCHandle directly.

// hold_object_reference.cpp  
// compile with: /clr  
#include "gcroot.h"  
using namespace System;  
  
#pragma managed  
class StringWrapper {  
  
private:  
   gcroot<String ^ > x;  
  
public:  
   StringWrapper() {  
      String ^ str = gcnew String("ManagedString");  
      x = str;  
   }  
  
   void PrintString() {  
      String ^ targetStr = x;  
      Console::WriteLine("StringWrapper::x == {0}", targetStr);  
   }  
};  
#pragma unmanaged  
int main() {  
   StringWrapper s;  
   s.PrintString();  
}  

StringWrapper::x == ManagedString  

GCHandle gives you a means to hold a managed object reference in unmanaged memory. You use the Alloc method to create an opaque handle to a managed object and Free to release it. Also, the Target method allows you to obtain the object reference back from the handle in managed code.

// hold_object_reference_2.cpp  
// compile with: /clr  
using namespace System;  
using namespace System::Runtime::InteropServices;  
  
#pragma managed  
class StringWrapper {  
   IntPtr m_handle;  
public:  
   StringWrapper() {  
      String ^ str = gcnew String("ManagedString");  
      m_handle = static_cast<IntPtr>(GCHandle::Alloc(str));  
   }  
   ~StringWrapper() {  
      static_cast<GCHandle>(m_handle).Free();  
   }  
  
   void PrintString() {  
      String ^ targetStr = safe_cast< String ^ >(static_cast<GCHandle>(m_handle).Target);  
      Console::WriteLine("StringWrapper::m_handle == {0}", targetStr);  
   }  
};  
  
#pragma unmanaged  
int main() {  
   StringWrapper s;   
   s.PrintString();  
}  

StringWrapper::m_handle == ManagedString  

Using C++ Interop (Implicit PInvoke)

Show: