非托管结构到托管封送处理
unmanaged struct to managed marshaling
我想将 ums 编组为 s(它们具有相似的对齐类型):
void F(ManagedStruct ^s)
{
ummanagedStruct ums;
FillTheStruct(&ums);
s = ?
}
我是否需要像这样使用 AllocHGlobal 分配非托管内存?:
void F(ManagedStruct ^s)
{
IntPtr ptr = Marshal::AllocHGlobal(Marshal::SizeOf(s);
FillTheStruct(static_cast<unmanagedStruct*>(ptr.ToPointer);
s = (ManagedStruct^)Marshal::PtrToStruct(ptr, ManagedStruct::typeid);
}
void F(ManagedStruct ^s)
如果您打算将值传回给调用者,那就错了。参数必须通过引用传递,以便可以更新调用者的变量。如果 "ManagedStruct" 实际上是一个值类型,那么 ^ 帽子也是错误的。您只能在引用类型上使用它,即您使用 ref struct
或 ref class
声明的类型。遗憾的是,C++/CLI 不会为此类用法生成诊断,它假定您有意将值装箱。
修复:
void F(ManagedStruct% s)
或者对于值类型来说通常更明智的一种:
ManagedStruct F() {
unmanagedStruct ums;
FillTheStruct(&ums);
return (ManagedStruct)Marshal::PtrToStructure(IntPtr(&ums), ManagedStruct::typeid);
}
请注意 Marshal::PtrToStructure() 很方便,但它既不安全也不比替代方法快,只需一个接一个地复制结构成员。
我想将 ums 编组为 s(它们具有相似的对齐类型):
void F(ManagedStruct ^s)
{
ummanagedStruct ums;
FillTheStruct(&ums);
s = ?
}
我是否需要像这样使用 AllocHGlobal 分配非托管内存?:
void F(ManagedStruct ^s)
{
IntPtr ptr = Marshal::AllocHGlobal(Marshal::SizeOf(s);
FillTheStruct(static_cast<unmanagedStruct*>(ptr.ToPointer);
s = (ManagedStruct^)Marshal::PtrToStruct(ptr, ManagedStruct::typeid);
}
void F(ManagedStruct ^s)
如果您打算将值传回给调用者,那就错了。参数必须通过引用传递,以便可以更新调用者的变量。如果 "ManagedStruct" 实际上是一个值类型,那么 ^ 帽子也是错误的。您只能在引用类型上使用它,即您使用 ref struct
或 ref class
声明的类型。遗憾的是,C++/CLI 不会为此类用法生成诊断,它假定您有意将值装箱。
修复:
void F(ManagedStruct% s)
或者对于值类型来说通常更明智的一种:
ManagedStruct F() {
unmanagedStruct ums;
FillTheStruct(&ums);
return (ManagedStruct)Marshal::PtrToStructure(IntPtr(&ums), ManagedStruct::typeid);
}
请注意 Marshal::PtrToStructure() 很方便,但它既不安全也不比替代方法快,只需一个接一个地复制结构成员。