这是与this SO post类似的问题,我无法用它来解决我的问题。我在这里添加了一些代码,希望能够帮助某人将其他帖子发布的消息带回家。
我想编写一个CLI / C ++方法,它可以将void指针作为参数并返回它指向的托管对象(我知道它的类型)。我有一个托管结构:
public ref struct ManagedStruct { double a; double b;};
我正在尝试编写的方法,它将一个指向托管结构的void指针作为参数并返回结构。
ManagedStruct^ VoidPointerToObject(void* data)
{
Object^ result = Marshal::PtrToStructure(IntPtr(data), Object::typeid);
return (ManagedStruct^)result;
}
这里调用方法:
int main(array<System::String ^> ^args)
{
// The instance of the managed type is created:
ManagedStruct^ myData = gcnew ManagedStruct();
myData->a = 1; myData->b = 2;
// Suppose there was a void pointer that pointed to this managed struct
void* voidPtr = &myData;
//A method to return the original struct from the void pointer
Object^ result = VoidPointerToObject(voidPtr);
return 0;
}
在调用VoidPointerToObject
时PtrToStructure
方法崩溃,错误:指定的结构必须是blittable或具有布局信息
我知道这是一个奇怪的事情,但这是我遇到过几次的情况,特别是当非托管代码对托管代码进行回调并将void *作为参数传递时。
答案 0 :(得分:13)
(原始说明如下)
如果您需要通过本机代码将托管句柄作为void*
传递,则应使用
void* voidPtr = GCHandle::ToIntPtr(GCHandle::Alloc(o)).ToPointer();
// ...
GCHandle h = GCHandle::FromIntPtr(IntPtr(voidPtr));
Object^ result = h.Target;
h.Free();
(或使用C ++ / CLI助手类gcroot
)
Marshal::PtrToStructure
适用于值类型。
在C ++ / CLI中,这意味着value class
或value struct
。尽管使用了关键字ref struct
,您仍在使用struct
,这是引用类型。
相关问题:
void* voidPtr = &myData;
没有指向对象,它指向句柄。
要创建托管堆上数据的本机指针,您需要使用固定。出于这个原因,void*
和Object^
之间的转换没有第一眼看上去那么有用。