将struct handle从managed转换为非托管C ++ / CLI

时间:2012-03-23 14:21:26

标签: c++ c++-cli unmanaged

在C#中,我定义了一个结构:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct MyObject
{
   [MarshalAs(UnmanagedType.LPWStr)]
   public string var1;    

   [MarshalAs(UnmanagedType.LPWStr)]
   public string  var2;    
};

我在C ++中有这个结构:

public value struct MyObject
{
    LPWSTR var1;    
    LPWSTR var2;    
};

在C ++的方法中,它是一个从C#调用的公共类:

TestingObject(MyObject^ configObject)
{
   // convert configObject from managed to unmanaged.
}

正确调试对象,我可以看到两个字符串var1和var2。但是,现在的问题是我需要将对象编组:configObject到非托管对象中。

我想到的是做这样的事情:

TestingObject(MyObject^ configObject)
{
   // convert configObject from managed to unmanaged.
   MyObject unmanagedObj = (MyObject)Marshal::PtrToStructure(configObject, MyObject);  
}

这是我能想到的,但当然,我得到了这个错误:

  

错误2错误C2275:'MyObject':非法使用此类型作为   表达

将托管对象转换为非托管对象是否正确?如果是这样,我怎样才能正确地Marshal::PtrToStructure?如果不是,我该怎么做?

2 个答案:

答案 0 :(得分:2)

Marshal::PtrToStructure与您想要的相反,它将非托管指针转换为托管对象。你想要Marshal::StructureToPtr

此外,您需要定义一个非托管类,因为MyObject是一个托管类型。假设你已经这样做了,你可以这样做(只是从C#样本中转换过来):

IntPtr pnt = Marshal::AllocHGlobal(Marshal::SizeOf(configObject)); 
Marshal.StructureToPtr(configObject, pnt, false);

然后你有一个指向数据的指针,你可以memcpy或者你原生结构中的任何内容。

但是 MyObject是并且将保持托管类型。如果您想要一个真正的非托管类型,您必须定义一个与托管结构匹配的类型。

只是想知道,为什么在托管结构中使用非托管LPWSTR?

答案 1 :(得分:1)

你可能意味着:

struct MyUnmanagedStruct {
    LPWSTR var1, var2;
};

然后您可以按照Botz3000的建议使用Marshal.StructureToPtr。否则就是C#的

public struct MyObject {
   public String var1;
   public String var2;
}

和C ++ / CLI的

public struct value MyObject {
   public String^ var1;
   public String^ var2;
}

是完全等效的,假设您在双方都使用相同的System.String