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

Ror*_*ory 4 pointers c++-cli command-line-interface

这个SO帖子也是一个类似的问题,我一直无法解决我的问题.我在这里添加了一些代码,希望能够帮助某人将其他帖子所传达的信息带回家.

我想编写一个CLI/C++方法,它可以将void指针作为参数,并返回它指向的托管对象(我知道它的类型).我有一个托管结构:

public ref struct ManagedStruct { double a; double b;};
Run Code Online (Sandbox Code Playgroud)

我正在尝试编写的方法,它将一个指向托管结构的void指针作为参数并返回结构.

ManagedStruct^ VoidPointerToObject(void* data)
{   
    Object^ result = Marshal::PtrToStructure(IntPtr(data), Object::typeid);
    return (ManagedStruct^)result;
}
Run Code Online (Sandbox Code Playgroud)

这里调用该方法:

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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

Ben*_*igt 14

(原作如下)

如果您需要将托管句柄作为void*直接本机代码传递,则应使用

void* voidPtr = GCHandle::ToIntPtr(GCHandle::Alloc(o)).ToPointer();

// ...

GCHandle h = GCHandle::FromIntPtr(IntPtr(voidPtr));
Object^ result = h.Target;
h.Free();
Run Code Online (Sandbox Code Playgroud)

(或使用C++/CLI助手类gcroot)


Marshal::PtrToStructure适用于价值类型.

在C++/CLI中,这意味着value classvalue struct.您正在使用ref struct,尽管使用了关键字,但这是一种引用类型struct.

一个相关的问题:

void* voidPtr = &myData;
Run Code Online (Sandbox Code Playgroud)

不指向对象,它指向句柄.

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