【问题标题】:Passing Structure from C++ CLI to Unmanaged Code将结构从 C++ CLI 传递到非托管代码
【发布时间】:2011-09-01 21:02:06
【问题描述】:

我有一个具有以下定义的非托管代码,

void Load(const somestruct& structinst)
    {
            //dosomething.
    } 

我想将 CLI 中的结构作为 ref 传递给非托管代码中的此方法,并在 CLI 中取回该结构。

我尝试在 CLI 中创建一个结构为

[StructLayout(LayoutKind::Sequential, CharSet = CharSet::Ansi, Pack = 2)]
 ref struct TEST
  {
      [MarshalAs(UnmanagedType::SysInt)]
      int k;
  };

并尝试将结构传递为

CLIWrapperClass::WrapperMethod()
{
  TEST test;
  this->NativeClassInstance->Load(test);
}

我收到类似error C2664: 'NativeClass::Load' : cannot convert parameter 1 from 'Namespace::WrapperClass::TEST' to 'NativeClass::somestruct&' 的错误

我将如何实现这一目标?

【问题讨论】:

  • 有很多地方出了问题。 ref struct 是托管代码中的一个类。您不要在 C++/CLI 中使用封送处理属性,该语言旨在处理该问题。但真正的问题是您刚刚声明了一个与非托管类型不同的托管类型。编译器不喜欢这样。写一个真正的包装器。

标签: visual-studio-2008 c++-cli marshalling


【解决方案1】:

如果你需要接触 C# 中的TEST 结构,请确保somestructTEST 结构具有相同大小的相同基本类型的相同成员。

如果没有,为什么还要打扰StructLayout?只需在 C++/CLI 中使用 somestruct 本身,例如:

CLIWrapperClass::WrapperMethod()
{
  somestruct test;
  this->NativeClassInstance->Load(test);
}

【讨论】:

  • 我没有投反对票,但声明“ref struct TEST 在 C# 中无法识别。它无效。”是错误的。 ref struct 只是一个托管引用类型,默认情况下具有公共(而不是私有)成员; C# 认为它与声明为 ref class 的托管引用类型完全不同——事实上,它们编译为完全相同的 IL。
【解决方案2】:

本机代码与垃圾收集器可以移动声音的 .net 类型不兼容。可以使用 pinning 和 cast,但这很脆弱。更好的方法是将数据从托管类型复制到本机结构的实例,然后再复制回来。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-27
    • 2013-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-01
    • 1970-01-01
    • 2013-03-06
    相关资源
    最近更新 更多