How can I send a managed entity to an inline function to use it?

How can I send a managed entity using an inline function?

void managed_function() { Object^ obj = gcnew Object(); void* ptr = obj ??? // How to convert Managed object to void*? unmanaged_function(ptr); } // The parameter type should be void* and I can not change the type. // This function is native but it uses managed object. Because type of ptr could not be // Object^ I called it "Unmanaged Function". void unmanaged_function(void* ptr) { Object^ obj = ptr ??? // How to convert void* to Managed object? obj->SomeManagedMethods(); } 
+4
source share
2 answers

After searching on Google, reading MSDN and checking some codes, I found this method for passing a managed object to an unmanaged function.

These methods show how to convert Object ^ to void * and convert void * to Object ^.

 using namespace System; using namespace System::Runtime::InteropServices; void managed_function() { Object^ obj = gcnew Object(); // Convert Object^ to void* GCHandle handle = GCHandle::Alloc(obj); IntPtr pointer = GCHandle::ToIntPtr(handle); void* ptr = pointer.ToPointer(); unmanaged_function(ptr); handle.Free(); } void unmanaged_function(void* ptr) { // Convert void* to Object^ IntPtr pointer(ptr); GCHandle handle = GCHandle::FromIntPtr(pointer); Object^ obj = (Object^)handle.Target; obj->SomeManagedMethods(); } 

Note: if "unmanaged_function" has variable arguments, this method will not work.

+7
source

A cleaner and better approach is to use gcroot .

Quote from MSDN How to declare descriptors in native types :

The gcroot template is implemented using the tools of the System :: Runtime :: InteropServices :: GCHandle value class, which provides pens to a bunch of garbage. Note that the descriptors themselves are not garbage collected and are freed when the descriptor is not used in the gcroot class (this destructor cannot be called manually). If you instantiate the gcroot object on the native heap, you must call delete on this resource.

Your code example uses 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; } 
+7
source

All Articles