The cleaner and the better approach is to use gcroot template.
A quote from MSDN How to: Declare Handles in Native Types:
The gcroot template is implemented using the facilities of the value class System::Runtime::InteropServices::GCHandle, which provides "handles" into the garbage-collected heap. Note that the handles themselves are not garbage collected and are freed when no longer in use by the destructor in the gcroot class (this destructor cannot be called manually). If you instantiate a gcroot object on the native heap, you must call delete on that resource.
Your sample code adapted to use gcroot
(the code compiles and runs using VS 2010):
using namespace System;
using namespace System::Runtime::InteropServices;
public ref class SomeManagedObject
{
public:
String^ data;
SomeManagedObject()
{
data = "Initial Data";
}
void SomeManagedMethods()
{
data = "Changed Data";
}
};
void unmanaged_function(void* ptr)
{
gcroot<SomeManagedObject^>& obj = *((gcroot<SomeManagedObject^>*)ptr);
obj->SomeManagedMethods();
}
void managed_function()
{
// gcroot handles all allocations/deallocation and convertions
gcroot<SomeManagedObject^>* pObj = new gcroot<SomeManagedObject^>();
*pObj = gcnew SomeManagedObject();
unmanaged_function(pObj);
delete pObj;
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…