How can I send a managed object to native function to use it?

前端 未结 2 1392
抹茶落季
抹茶落季 2020-12-16 06:55

How can I send a managed object to native function to use it?

void managed_function()
{
  Object^ obj = gcnew Object();

  void* ptr = obj ??? // How to conv         


        
相关标签:
2条回答
  • 2020-12-16 07:10

    After googling, reading MSDN and try some codes, I found this method to pass 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 won't work.

    0 讨论(0)
  • 2020-12-16 07:18

    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;
    } 
    
    0 讨论(0)
提交回复
热议问题