非托管结构到托管封送处理

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 structref class 声明的类型。遗憾的是,C++/CLI 不会为此类用法生成诊断,它假定您有意将值装箱。

修复:

  void F(ManagedStruct% s)

或者对于值类型来说通常更明智的一种:

  ManagedStruct F() {
      unmanagedStruct ums;
      FillTheStruct(&ums);
      return (ManagedStruct)Marshal::PtrToStructure(IntPtr(&ums), ManagedStruct::typeid);
  }

请注意 Marshal::PtrToStructure() 很方便,但它既不安全也不比替代方法快,只需一个接一个地复制结构成员。