Ami*_*yan 5 .net mixed-mode unmanaged c++-cli managed
如何将托管对象发送到本机函数以使用它?
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();
}
Run Code Online (Sandbox Code Playgroud)
Ami*_*yan 10
在谷歌搜索,阅读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();
}
Run Code Online (Sandbox Code Playgroud)
注意:如果"unmanaged_function"具有可变参数,则此方法将不起作用.
Edd*_*erg 10
更清洁,更好的方法是使用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;
}
Run Code Online (Sandbox Code Playgroud)