CLI / C ++:void *到System :: Object

时间:2011-08-01 19:15:59

标签: pointers c++-cli command-line-interface

这是与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;
}

在调用VoidPointerToObjectPtrToStructure方法崩溃,错误:指定的结构必须是blittable或具有布局信息

我知道这是一个奇怪的事情,但这是我遇到过几次的情况,特别是当非托管代码对托管代码进行回调并将void *作为参数传递时。

1 个答案:

答案 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 classvalue struct。尽管使用了关键字ref struct,您仍在使用struct,这是引用类型

相关问题:

void* voidPtr = &myData;

没有指向对象,它指向句柄。

要创建托管堆上数据的本机指针,您需要使用固定。出于这个原因,void*Object^之间的转换没有第一眼看上去那么有用。