在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
?如果不是,我该怎么做?
答案 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
。