CLI / C ++:void * to System :: Object [英] CLI/C++: void* to System::Object
问题描述
这是一个类似于此SO帖的问题,我有无法使用来解决我的问题。我已经在这里包括一些代码,这将有希望帮助别人带来的消息,其他发布正在得到。
我想编写一个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)
{
//创建托管类型的实例:
ManagedStruct ^ myData = gcnew ManagedStruct();
myData-> a = 1; myData-> b = 2;
//假设有一个void指针指向这个托管结构
void * voidPtr =& myData;
//从void指针返回原始结构的方法
对象^ result = VoidPointerToObject(voidPtr);
return 0;
}
它在 VoidPointerToObject
方法调用 PtrToStructure
时出现错误:指定的结构必须是可布局的或具有布局信息
我知道这是一个奇怪的事情,但它是一种情况,我已经遇到了几次,特别是当非托管代码回调托管代码,并传递一个void *作为参数。
(以下原始解释)
一个托管句柄作为 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
> value types 。
value class
或 value struct
。尽管使用了关键字 struct
,但仍使用 ref struct
相关问题:
void * voidPtr = myData;
不指向对象,它指向句柄。
为了创建一个指向托管堆上的数据的本地指针,你需要使用固定。因此, void *
和 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 to 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.
这篇关于CLI / C ++:void * to System :: Object的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!