【问题标题】:Using COM to marshal a C# struct from C++ code使用 COM 从 C++ 代码中编组 C# 结构
【发布时间】:2014-07-30 11:34:44
【问题描述】:

不久前,我有一个 C# 程序需要调用 C++ dll 中的一些函数。为此,我使用了 pInvoke。我需要传入的一些数据是结构体。因此,我将使用 pInvoke Signature Toolkit 来了解如何创建与 C++ 函数通过引用获取的结构等效的 C# 结构。然后,我能够将这些结构传递给 C++ 代码。

现在,我的情况正好相反。我在 C++ 代码中,我正在收到 _com_ptr_t 对象。这本质上是一个指向 C# 对象的指针。 C# 对象实现了一个具有 get_Foo、set_Foo 等属性的 COM 接口,我可以使用这些接口从 C# 对象中提取值(通常,它们只是基本数据类型,如 float、bool、int 等)并填充它们进入我的 C++ 对应部分。

这很好用,但有点慢。当我分析我的代码时,它会在“clr”中花费大量时间。所以,我希望找到一种更快的方法,我可以在其中向 COM 接口添加一个函数,该函数将立即将整个 C# 对象复制到 C++ 对应结构中——就像我在上面使用 pInvoke 所做的那样,除了我通过 COM 接口从 C++ 代码中提取数据,而不是通过 pInvoke 接口将数据传递给 C++ 代码。

有人知道怎么做吗?

【问题讨论】:

  • 每个 CLR -> COM 需要将托管缓冲区复制到非托管缓冲区。这总是很慢。引用 Alan Gordon(.NET 和 COM 互操作性手册):避免使用健谈的界面。
  • 嗨,马特。它只需要大约一毫秒半,但是我的整个程序只有大约 16.7 毫秒可以使用,因此它最终很重要。谢谢,Andro47。这个界面确实很健谈。想象一个具有几十个属性的 C# 对象(每个属性都是基本数据类型,如 float 或 int)。在 C++ 方面,每个属性都被转换为单独的 get_X 和 set_X 方法。要将对象复制到 C++ 中,我必须为每个属性调用 get_ 方法。然后对数百个对象执行此操作。耶!

标签: c++ .net com marshalling


【解决方案1】:

您可以使用 IDL 在 COM 中传递structs,这可能会或可能不会加速数据传输。很有可能它会提高数据复制的速度,因为您的往返次数较少,但如果您在 CLR 方面花费大量时间的原因是因为它在做额外的工作复制数据,优化数据传输本身并不会真正加快速度。

这是您必须为双方(本机和 CLR)提供分析结果的情况之一,因为否则您几乎可以保证优化错误的内容。

【讨论】:

  • 非常感谢!我对IDL不是很熟悉,但我会做一些研究。在大多数情况下,这些对 CLR 的调用只是基本数据类型的 C# 属性(例如,名为 PositionX 的浮点属性在 C++ 接口上显示为单独的 get_PositionX 和 set_PositionX 方法),它们所做的只是复制数据。其中一些对象有几十个这样的调用,只是为了复制一个对象,所以我希望这会提供一点速度提升。再次感谢。
  • 如果他们真的只是在复制数据,那么是的,将它们放入一个结构中应该会大大提高性能。
猜你喜欢
  • 2019-06-27
  • 2014-10-07
  • 1970-01-01
  • 2010-12-17
  • 2012-09-12
  • 1970-01-01
  • 2010-11-20
  • 2017-07-17
  • 1970-01-01
相关资源
最近更新 更多