快速C ++程序,C#GUI,可能吗?

我正在研究开发一种应用程序,它将以每秒约2000行(帧)的速度处理来自线扫描相机的数据。 对于这个实时应用程序,我觉得C / C ++是要走的路。 (这是我的感觉,其他人会同意托管代码不适合这项任务。)

但是,我做了很少的MFC或任何其他C ++ GUI。 不过,我真的很想做C#GUI。

所以我很自然地用C / C ++编写数据密集型代码,用C#编写GUI。 GUI将用于设置/校准/在线监控(并可能通过UDP输出数据,因为它在C#中更容易。

首先,我想看看是否有人同意这是可行的方法。 根据我的编程经验(擅长低级C算法和高级C#GUI设计),它感觉恰到好处。

其次,我不确定正确的方法。 我只是在VS2005中汇总了一个解决方案,该解决方案从C#app调用了一些(extern“C”)DLL函数。 为了确保我能做到,我写了DLL中的一些全局变量,并从中读取:

test.h

int globaldata; extern "C" __declspec(dllexport) void set(int); extern "C" __declspec(dllexport) int get(); 

TEST.CPP

 extern int data=0; __declspec(dllexport) void set(int num) { data = num; } __declspec(dllexport) int get() { return data; } 

test.cs中

 [DllImport("test")] private static extern void set(int num); [DllImport("test")] private static extern int get(); 

调用get()set()正常工作( get()返回我传递给set() )。

现在,我知道您也可以导出C ++类,但它是否必须进行管理? 这是如何运作的? 我是以正确的方式来做这件事的吗?

感谢你的帮助!

*** EDIT ***

首先, 感谢您迄今为止的精彩答案! 我总是对Stack Overflow印象深刻……

我想我应该注意的一件事,不一定是原始速度(这可以是原型和基准测试)。 让我更关心的一件事是垃圾收集器的非确定性行为。 执行垃圾收集时,此应用程序不能容忍500毫秒的延迟。

我只是编写代码并在纯C#中尝试这个,但如果我提前知道GC和任何其他非确定性的.NET行为(?)会导致问题,我认为我的时间会更好地用于编码C / C ++并找出最好的C#接口。

没有理由不能完全用C#编写高性能代码

  • 性能(C#编程指南)

  • Rico Mariani的表演博客 (一个很好的资源)

  • 调整.NET应用程序性能

关于相同/类似主题的问题:

  • C ++性能与Java / C#
  • c ++比c#快多少?

其他文章:

  • Microbenchmarking C ++,C#和Java
  • 利用C#的特点为您的科学计算项目提供动力
  • 使用Visual Studio Profiler查找应用程序瓶颈
  • 揭穿C#与C ++性能

在我看来,你的解决方案是合理的:

  1. 尽管C#速度很快,但它永远无法与编写良好的非托管C / C ++竞争,我自己制作了高性能的应用程序,certificate了这一点超出了当有人发布这些语句时人们总是发布的小例子
  2. MFC或ATL UI编程繁琐而且速度慢,C#是走到这里的方式,我永远不会再做MFC / ATL UI编程,除非被迫

你的解决方案,如果你还没有想到它,被称为“混合模式”,这基本上意味着你在同一个项目中结合托管(C#)和非托管(C / C ++)代码,它通常是一点点让VS项目运行起来很麻烦(LNK2020错误……)..但是当你找到合适的设置时它应该可以正常工作。

唯一不好的是混合模式程序集必须以完全信任方式运行,如果可以,那么我想你知道该怎么做。

您可能想要了解的另一件事是一个名为SWIG的开源项目。 SWIG接受你的C / C ++代码并用它创建一个.NET程序集,我在我的TM ++开源项目中自己使用它。 有关SWIG http://www.swig.org/的更多信息,请参见此处。

对于实时应用程序:我推荐使用C ++,根据使用的框架,你将更灵活地进行内存管理,更快,甚至是多平台…!

关于框架和GUI,我建议你看看Qt 。 Qt是一个很好的C ++软件开发框架。

我想这是你问题的解决方案!

你需要做的第一件事是测试你的假设 。 你的性能限制是什么? 您希望托管应用程序的硬件类型是什么? 在C#中编写一个小程序来处理核心问题并测量其运行速度。

只有掌握了事实后,才能决定是否在托管解决方案上使用C / C ++。

与其他评论过的人一起,我怀疑C#/托管解决方案会做得很好,特别是如果你使用.NET Parallel Extensions 。

如果你最终进入C / C ++路由,那么有两个选项可以互操作,即pInvoke和COM互操作 。 我不相信有一种直接从.NET访问非托管C ++类的简洁方法; 为此,您必须考虑实现托管/非托管C ++程序集 。

虽然用CCD相机代替线扫描相机,但我的公司做的事情非常相似。 我们使用C#进行GUI,网络通信,高级“管道”和低级算法的C ++ / CLI。 它运作得很好。 你永远无法编写一个真正的实时系统,保证在Windows上有最长的响应时间,但根据我的经验,GC将是你在这里遇到的最少的问题。 首先,GC只在你分配内存时运行; C / C ++中的malloc / new也是如此,它们也需要时间(想想内存碎片)。 根据我们已经完成的测量,一个完整的GC需要10-50ms,并且在那段时间内不会成功停止其他线程(除非他们尝试分配管理内存,我认为),这对我们来说没问题。 但是我不确定这些数字是否可以推广到任何类型的应用程序,你可能应该自己进行分析以确定。

如果您担心GUI可能会破坏您的实时约束,您可以考虑将实际的图像处理放入一个单独的进程中,并使用管道/套接字与GUI进行通信。 或者至少在设计系统时要记住这个选项,所以如果你真的遇到了不可预见的性能问题,那么你将它作为最坏的选择。

您的第二个问题是您是否应该使用C ++或C#作为实际算法。 就个人而言,当我编写复杂的图像处理算法时,我觉得在C ++中更加平易近人。 我认为该语言更适合于该任务,并且C / C ++的数字库比C#要多得多。 但这可能是个人偏好的问题。 从性能的角度来看,C ++的优势在于C ++内联器优于.NET JIT内联器(即它可以内联更多的小函数调用)。

如果您选择使用C ++,我建议使用C ++ / CLI:这样,您可以编写编译为托管代码的C ++类。 C ++优化器将优化它们,只有.NET JIT才能完成对本机代码的最后编译步骤。 最大的优点是您可以直接从C ++ / CLI访问.NET类,并且可以轻松地在C ++ / CLI中创建可以从C#访问的托管类。 您不需要在围栅的两侧编写包装代码。 (C ++ / CLI有点笨重,因为它包含用于托管和非托管编程的语言结构,但如果您已经熟悉非托管C ++和C#,那么理解它可能不会有任何问题。)

对于C ++,您使用C ++ / CLI – 实际上并没有那么糟糕。 它比旧的托管扩展要好得多。

评论表现。 这真的取决于。 你的C ++代码和C#代码之间会有多少来回? 你有一个后台线程用C ++收集数据并定期发送给C#代码吗? 如果您要与设备连接,是否会使用串口,​​USB,某些API?

我同意Mitch 100%。

如果在调查他的资源之后,你仍然觉得你需要使用一些非托管代码,你可以在C ++中编写一个“业务”层(或者在这种情况下,实际上是一个function层)并用C#编写你的UI。 使用COM Interop从C#/托管代码调用非托管代码。

但是,我的感觉是,你不需要这样做。

您选择的语言不会对性能产生太大影响(比如说您可以将速度提高5/10%)。 将产生差异的是您将使用的算法,如何处理数据,分析您的应用程序等……(性能可能会以10倍的比例变化)。

我用C ++ .NET完成了它

由于C ++ .NET和C#都是托管的,我不明白为什么不能这样做。 关键是你将如何做到这一点。

我的扫描仪最高可达3000行/秒,但关键策略是一次显示32行的块。 我没有硬实时要求,所以有时我可能会有点落后。 如果实时对您非常重要,您应该考虑切换平台。

有一个名为“InTime OS”的实时Windows解决方案,但使用它真的很痛苦。

您可以拥有的另一种方法是将硬实时分离到单独的dll或库中,让C#以自己的速度显示它可以实现的function。 实际上,用户永远无法判断您的界面是否具有2000 fps或500 fps

我有本机C / C ++和C#极低延迟系统的经验。

  • 在C / C ++中,80%的处理器时间在确定性malloc方法中丢失,但本机代码比msil代码快10倍

  • 在C#内存分配更快,因为它是一个异步进程

您的选择必须通过以下比率来完成:处理时间/ malloc编号

所以粒度!!!

C / C ++的解决方案是在内存中预分配所有缓冲区(如果需要,使用预取L2 / L3缓存)

C#的解决方案是最小化P-Invoke转换机制

恭喜你的项目,保罗

前端wpf和c ++后端(pinvoke)很快,但是当您在线程上执行GUI工作时,您的GUI线程也不会被后台代码阻止。 当你这样做时,你的程序看起来会更快,重量更轻。

为何选择Windows? 与任何unixes相比,它具有可怕的内存性能和更糟糕的网络。 专门捕获线传感器意味着您需要一个设备来处理原始输入。 考虑首先使用正确的操作系统,这将大大降低您必须处理的其他压力(我对线扫描仪技术非常熟悉)。