管理编组的非托管结构

时间:2015-07-13 11:53:48

标签: .net c++-cli interop

我想将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);
}

1 个答案:

答案 0 :(得分:1)

   void F(ManagedStruct ^s)

如果您打算将值传递给调用者,那就错了。参数必须通过引用传递,以便可以更新调用者的变量。如果“ManagedStruct”实际上是值类型,那么^ hat也是错误的。您只能在引用类型上使用它,即使用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()很方便,但它既不比替代方法更安全也更快,只需逐个复制结构成员。