如何将托管对象发送给本机函数来使用它



如何将托管对象发送给本机函数来使用它?

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

更简洁、更好的方法是使用groot模板。

来自MSDN的引语:如何:在本机类型中声明句柄:

gcroot模板是使用值类System::Runtime::InteropServices::GCHandle的功能实现的,它为垃圾收集堆提供"句柄"。请注意,句柄本身不会被垃圾收集,并且在groroot类中的析构函数不再使用时释放(这个析构函数不能手动调用)。如果您在本机堆上实例化一个groot对象,则必须对该资源调用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;
} 

在谷歌搜索,阅读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"有可变参数,此方法将不起作用。

相关内容

  • 没有找到相关文章

最新更新