Как я могу отправить управляемый объект в собственную функцию, чтобы использовать его? - PullRequest
5 голосов
/ 10 сентября 2011

Как я могу отправить управляемый объект в собственную функцию, чтобы использовать его?

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();
}

Ответы [ 2 ]

9 голосов
/ 06 февраля 2013

Чем чище и лучше использовать шаблон gcroot .

Цитата из MSDN Как: объявить дескрипторы в собственных типах :

Шаблон gcroot реализован с использованием средств класса значений System :: Runtime :: InteropServices :: GCHandle, который обеспечивает «дескрипторы» в куче, собираемой мусором. Обратите внимание, что сами дескрипторы не собираются мусором и освобождаются, когда деструктор в классе gcroot больше не используется (этот деструктор нельзя вызвать вручную). Если вы создаете экземпляр объекта gcroot в собственной куче, вы должны вызвать delete для этого ресурса.

Ваш пример кода адаптирован для использования gcroot (код компилируется и запускается с использованием 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;
} 
9 голосов
/ 10 сентября 2011

После поиска в Google, чтения MSDN и проверки некоторых кодов, я нашел этот метод для передачи управляемого объекта в неуправляемую функцию.

Эти методы показывают, как преобразовать Object ^ в void * и преобразовать void * в 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();
} 

Примечание: если "unmanaged_function" имеет переменные аргументы, этот метод не будет работать.

...