【问题标题】:Wrapping unmanaged C++ templates in C++/CLI for C#/.NET use在 C++/CLI 中包装非托管 C++ 模板以供 C#/.NET 使用
【发布时间】:2013-06-28 11:13:32
【问题描述】:

如果有人问过这个问题,请接受我的道歉。我似乎找不到太多关于这个主题的东西。 Primitive types pass template parameter between c++ and CLI 是一个类似的问题,我觉得它的信息量不大。

我有一个本机 C++ DLL,它公开了一个模板类(当然是它的实例化),我想在 C# 中模拟它。我对 C# 比较陌生,但我知道最接近的是泛型。

我的问题是如何将 C++ 模板包装在 C++/CLI 模板/泛型中,以便能够在 C# 中使用它。

  1. 有可能吗?我认为这是不可能的,因为 CLI 包装器不知道如何将非托管的未知类型 T 编组为托管类型以供 C# 使用。

  2. 如果可能,你会怎么做?如果不是,您可以在类似情况下使用哪些一般策略?

谢谢。

【问题讨论】:

  • C++ 模板在编译时被实例化。从托管代码中使用它们的唯一可能方法是让它运行 C++ 编译器。这当然不实用。在 C++/CLI 中使用 generic 关键字来声明在运行时实例化的泛型类型。

标签: c# c++ .net templates c++-cli


【解决方案1】:

假设您说的是非托管C++,那么这实际上是不可能的。

一般来说,将任何复杂的东西从非托管 C++ 传递到 C# 都是一种痛苦。

最简单的做法是用 C++ 编写一个简单的结构,您可以使用它在托管代码和非托管代码之间传递数据。 (换句话说,一个数据传输对象。)

然后编写一个封装C++ 方法的非托管函数(使用C 签名而不是名称混乱的C++ 签名),然后从C# 调用该封装函数。

我已经这样做了几次,它比尝试从 C# 调用非托管 C++ 函数要容易得多!

【讨论】:

  • 感谢您的回复!是的,我说的是非托管 C++(我在编辑中澄清了这一点)。那么在您的解决方案中,您是否完全绕过了托管 C++ 包装器?
  • @KristianD'Amato 是的,在我的代码中,我用 C 函数包装了所有 C++ 内容,并将必要的数据从复杂的 C++ 类复制到非常简单的 C 结构中。
【解决方案2】:

您说模板类已经从DLL中导出,这意味着它是一个实例化的模板类。

从 P/Invoke 的角度来看,实例化的 C++ 类与常规 C++ 类没有区别。无需使用 C++/CLI 直接从 C# 调用实例化模板类是可行的,尽管手动编写包装器代码将非常耗时。

我已经在 C# pinvoke marshalling structure containg vector<structure> 的 stackoverflow 上分享了手动执行此操作的方法,但是以这种方式手动编写包装器类会花费您太多时间,可能不值得。

我写的工具xInterop NGen++可以为模板类生成C#包装类。它可以为从本地 C++ DLL 导出的任何 C++ 类生成包装类,只要可以从传统 C++ 应用程序中使用相同的 DLL。

您可能希望在我的博客网站上的以下链接中阅读详细信息。

Advanced technology to wrap native C++ template class in C# automatically

Creating and Accessing Instantiated std::vector Template Class from .NET

如果您担心预算,我确实计划在不久的将来免费发布快速版本。因此,如果您有一个需要调用几个 C++ 模板类的小项目,您也许可以使用功能有限的免费版本来创建 C# 包装类。我还计划为几个开源 C++ 项目发布生成的 C# 包装器(C# 绑定)。

(我是xInterop NGen++的作者)

【讨论】:

  • 我一直在为我们公司评估这个工具,并且对它的覆盖水平和它实现的用例数量印象深刻。如果您对 C++ 进行了大量投资并且需要能够从 C#/VB.Net 应用程序中使用它,这是一款非常好的产品。
【解决方案3】:

如果您愿意在 C++/CLI 包装器中为这些类型提供支持的模板参数类型和托管非托管转换函数的明确列表,这是可行的。 See the code here.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-14
    • 1970-01-01
    相关资源
    最近更新 更多