开发者

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

This is a similar question to this SO post, which I have been unable to use to solve my problem. I have included some code here, which will hopefully help someone to bring home the message that the other posting was getting at.

I want to write a CLI/C++ method that can take a void pointer as a parameter and return the managed object (whose type I know) that it points to. I have a managed struct:

public ref struct ManagedStruct { double a; double b;};

The method I am trying to write, which takes a void pointer to the managed struct as a parameter and returns the struct.

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

The method is called here:

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

It crashes in the VoidPointerToObject method on calling PtrToStructure , with the error: The specified structure must be blittable or have layout information

I know this is an odd thing to do, but it is a situation I have encountered a few times, especially when unmanaged code makes a callback t开发者_StackOverflow社区o managed code and passes a void* as a parameter.


(original explanation below)

If you need to pass a managed handle as a void* through native code, you should use

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

// ...

GCHandle h = GCHandle::FromIntPtr(IntPtr(voidPtr));
Object^ result = h.Target;
h.Free();

(or use the C++/CLI helper class gcroot)


Marshal::PtrToStructure works on value types.

In C++/CLI, that means value class or value struct. You are using ref struct, which is a reference type despite use of the keyword struct.

A related problem:

void* voidPtr = &myData;

doesn't point to the object, it points to the handle.

In order to create a native pointer to data on the managed heap, you need to use pinning. For this reason, conversion between void* and Object^ isn't as useful as first glance suggests.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜