我们有执行高性能数据处理的遗留 C++ 代码(例如,从硬件设备馈送的大量数据以时间敏感的方式处理以显示、转换和传输到二级存储)。
我们对 C#/.NET 的新 GUI 和新实用程序感兴趣(现有 GUI 是 C++ MFC 和 Qt)。当然,对于现有系统,我们不存在 .NET 虚拟机的“语言翻译”问题(现有代码都是 C++)。
经过大量研究和大量书籍,我不确定这是否可以有效地完成。可能的方法(我是否遗漏了任何方法?):
我们对 (2)“瘦适配器层”的担忧是,如果 GUI 可以(重新)使用“业务”层中的逻辑(许多属性是算法派生的),那将会很好,所以如果我们不如果不公开/包装 C++ 类,许多 GUI 逻辑只会复制业务层中现有的 C++ 逻辑。
我们对 (3)“厚适配器层”的担忧是,用 C# 类包装每个 C++ 类似乎非常乏味(昂贵),并且有几本书建议跨该边界的装箱/拆箱访问似乎建议这种方法非常不可行/令人望而却步(它的性能超出了琐碎的设计)。
您将如何在用 C++ 实现的深度类结构之上连接新的 C#/.NET (GUI)?
最佳答案
C++/CLI 非常适合这个。托管/非托管转换没有性能问题,因为 C++/CLI 使用与 .NET 运行时引擎本身相同的优化调用技术来实现字符串连接等高性能方法。
当您在同一数据结构的 .NET 和 native 版本之间来回复制数据时,会出现性能问题,但是您会遇到同样的问题,例如将使用 BSTR 的库与使用 std::string
的库一起使用,缓慢的操作同样明显(不像 P/Invoke,它试图使这些转换透明,并最终隐藏性能过程中的问题)。
您还可以使用一些技巧来克服这个问题。例如,不是将 std::vector
复制到 System::Collections::Generic::List
中,而是直接实现一个 IEnumerator
从 std::vector
中读取。
当然,如果数据只是直接传递回另一个 C++ 函数,则根本没有理由将其转换为托管类型。同样,C++/CLI 使保留格式变得容易,其中 P/Invoke 会尝试在您背后转换所有内容。
总而言之,“瘦”C++/CLI 包装层是您的最佳选择。
https://stackoverflow.com/questions/5996297/