CLI / C ++:void * to System :: Object [英] CLI/C++: void* to System::Object

查看:244
本文介绍了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 。

在C ++ / CLI中,这意味着 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆