【问题标题】:C++ backend with C# frontend?C++ 后端与 C# 前端?
【发布时间】:2011-05-02 19:26:35
【问题描述】:

我有一个项目,在该项目中,我必须每秒处理 100 条消息(如果不是 1000 条消息),并相应地在图表上处理/绘制这些数据。 (用户将搜索一组数据,其中将实时绘制图形,而不必在图形上绘制 1000 个值。)

我无法理解使用 DLL 在 C++ 中处理大量消息,然后将信息传递给 C# 接口。有人可以在这里为我简化一下吗?

另外,由于速度将是一个优先事项,我想知道访问 2 个不同的代码层是否会比使用 C# 或 C++ 对整个项目进行编程对性能产生更大的影响。但是,我读过关于用 C++ 编写 GUI 的坏事。在这方面,这个应用程序还必须看起来现代、干净、专业等。所以我认为 C# 将是前进的方向(可能是 XAML、WPF)。

感谢您的宝贵时间。

【问题讨论】:

  • 几 1000 条消息并不多。除非它们真的很复杂,否则 C# 也应该能够使用它们。 C++ 提供了不错的 GUI 库(QT 应该没问题)。所以我认为所有三种解决方案都可能可行。
  • 抱歉,我刚看到你的评论。干杯:D 我不确定任何时候 1000-2000 条消息是否很多。我在下面发布了这个“实际上,我将获取每条消息并对其进行解析,以人类可读的形式将其存储,然后在 GUI 中显示它。据我所知,解析和存储将继续发生,而某些GUI 的元素,例如图形、表格将按需显示(查询数据/用户交互)”有什么想法吗?再次感谢您的帮助!
  • “解析”是什么意思,有多复杂?以人类可读的形式存储有多复杂?
  • 抱歉,我的意思是数据一开始是不可读的,但我必须对每条消息进行转换,以便以易于阅读的方式存储它输出到要读取的屏幕。例如,如果我从交易所获取数据,我想存储它,以便用户可以轻松查看最佳出价/最佳要价 + 其他相关信息。这是否完全清除了它?
  • 老实说,我不明白这个讨论...您是否担心如果用 C# 编写(在您尝试之前)您的数据转换可能会很慢?

标签: c# c++ wpf user-interface performance


【解决方案1】:

如果速度是您的首要任务,C++ 可能是更好的选择。尝试对计算的真正难度做出一些估计(如果每条消息的计算很容易,那么在 C# 中处理 1000 条消息可能是微不足道的,即使是最优化的程序也可能太难了)。如果您的算法很复杂,涉及不同的类等,C++ 可能比 C# 具有更多优势(在性能方面)。

您可能需要查看this question 以进行性能比较。

分离后端和前端是个好主意。一个在 C++ 中而另一个在 C# 中是否会降低性能取决于实际需要多少数据转​​换。

我不认为对 GUI 进行编程通常是一件痛苦的事。 MFC 可能很痛苦,Qt 不是(恕我直言)。

也许这会给你一些起点!

【讨论】:

    【解决方案2】:

    在 C/C++ DLL 和 .NET 程序集之间进行互操作的最简单方法是通过 p/invoke。在 C/C++ 端,像创建其他任何 DLL 一样创建 DLL。在 C# 端,您创建一个 p/invoke 声明。例如,假设您的 DLL 是 mydll.dll,它导出了一个方法 void Foo()

    [DllImport("mydll.dll")]
    extern static void Foo();
    

    就是这样。您只需像任何其他静态类方法一样调用 Foo 。困难的部分是整理数据,这是一个复杂的主题。如果您正在编写 DLL,您可能会竭尽全力使导出函数易于编组。有关 p/invoke 编组的更多信息,请参见此处:http://msdn.microsoft.com/en-us/magazine/cc164123.aspx

    使用 p/invoke 会影响性能。每次托管应用程序进行非托管方法调用时,它都会跨越托管/非托管边界然后再次返回。当您编组数据时,会进行大量复制。如有必要,可以使用“不安全”的 C# 代码(使用指针直接访问非托管内存)来减少复制。

    您应该注意的是,所有 .NET 应用程序都充满了 p/invoke 调用。没有 .NET 应用程序可以避免进行操作系统调用,并且每个操作系统调用都必须进入操作系统的非托管世界。 WinForms 甚至 WPF GUI 应用程序使这一过程每秒数百甚至数千次。

    如果这是我的任务,我会首先 100% 用 C# 来完成。然后我会对其进行分析并根据需要调整性能。

    【讨论】:

    • 哪个更简单尚有争议,但 C++ 互操作(通过将 /clr 传递给 Visual C++ 编译器)肯定比 p/invoke 快。
    • 我想我开始倾向于 C# 选项。我应该提一下,在我了解 C# 之前,我实际上必须学习 C++。我一直在读到,只有当这个人是优化专家时,C++ 才会更快,在这种情况下,对于 C++ 来说,这绝对不会是这样。为您的帮助干杯。
    【解决方案3】:

    如果您有 C/C++ 源代码,请考虑将其链接到 C++/CLI .NET 程序集。这种项目允许您混合非托管代码并在其上放置托管接口。结果是一个简单的 .NET 程序集,在 C# 或 VB.NET 项目中使用起来很简单。

    内置了简单类型的编组,因此您可以将函数从托管 C++ 端调用到非托管端。

    您唯一需要注意的是,当您将委托编组为函数指针时,它不保存引用,因此如果您需要 C++ 保存托管回调,则需要安排引用将要举行。除此之外,大多数内置转换按预期工作。 Visual Studio 甚至可以让你跨界调试(开启非托管调试)。

    如果你有一个 .lib,只要它动态链接到 C-Runtime,你就可以在 C++/CLI 项目中使用它。

    【讨论】:

      【解决方案4】:

      在开始将数据编组和解组为不安全的结构之前,您应该真正在 C# 中进行原型设计,以便您可以调用 C++ DLL 中的函数。 C# 通常比您想象的要快。原型制作很便宜。

      【讨论】:

      • 我真的没有时间制作它的原型,因为这将是我的最后一年项目,但我想我会完全用 C# 编写它。干杯:)
      • 嗯,好的,但是关于原型设计的一个关键点是它不需要很多时间。这也是了解 Fred Brooks 所说的“建造一个扔掉”时所说的快速方法。
      【解决方案5】:

      另一种可能的方法:听起来这个任务是并行化的主要目标。以这样一种方式构建您的应用程序,它可以将其工作负载分配到多个 CPU 内核甚至不同的机器上。然后你可以通过向它们扔硬件来解决你的性能问题(如果有的话)。

      【讨论】:

      • 这其实是个好主意,我从来没想过。我需要对其进行一些研究,但为这个想法欢呼!
      • @Sparky - 毫不犹豫地通过投票来表达你的感激之情! ;)
      • 我还不能投票 :( 我已经在上面说过了...什么时候可以。
      • @Sparky - 你已经被有能力向上投票的力量所祝福,无论是提问、回答还是评论。明智地使用它!
      猜你喜欢
      • 1970-01-01
      • 2011-11-08
      • 2011-02-06
      • 2011-09-12
      • 2021-07-05
      • 1970-01-01
      • 1970-01-01
      • 2020-01-30
      • 2019-07-17
      相关资源
      最近更新 更多