使用C#前端的C ++后端?

时间:2010-10-30 13:08:37

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

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

我无法理解使用dll在C ++中进行大量的消息处理,然后将信息传递到C#接口。有人可以在这里为我愚蠢吗?

此外,由于速度将是一个优先级,我想知道是否访问2个不同的代码层将有更多的性能命中,在C#中完整地编程项目,或者当然我读过有关C ++的坏东西用C ++编写GUI,其中,这个应用程序也必须看起来现代,干净,专业等等所以我认为C#将是前进的方向(也许是XAML,wPF)

感谢您的时间。

5 个答案:

答案 0 :(得分:6)

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

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

抄袭后端和前端是一个好主意。如果在C ++中使用C#而导致性能下降,C#取决于实际需要多少数据转​​换。

我不认为编程GUI是一般的痛苦。 MFC可能很痛苦,Qt不是(恕我直言)。

也许这会给你一些开始点!

答案 1 :(得分:6)

在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应用程序可以避免进行操作系统调用,并且每个OS调用都必须进入操作系统的非托管世界。 WinForms甚至WPF GUI应用程序使这一旅程每秒数百甚至数千次。

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

答案 2 :(得分:4)

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

答案 3 :(得分:2)

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

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

你唯一需要注意的是,当你将一个委托编组成一个函数指针时,它没有一个引用,所以如果你需要C ++来保存托管回调,你需要安排一个参考举行。除此之外,大多数内置转换都按预期工作。 Visual Studio甚至可以让您跨越边界进行调试(打开非托管调试)。

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

答案 4 :(得分:1)

在开始使用编组和解组数据到不安全的结构之前,你应该在C#中对它进行原型设计,以便可以调用C ++ DLL中的函数。 C#通常比你想象的要快。原型设计很便宜。