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

Fast C++ program, C# GUI, possible?

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

但是,我已经做了很少的MFC,或者任何其他的C++ GUI。不过,我真的要把C guis做好了。

所以在C/C++中编写数据密集型代码和C语言中的GUI是很自然的。图形用户界面将用于设置/校准/在线监测(并可能通过UDP输出数据,因为它在C中更容易实现)。

所以首先,我想看看是否有人同意这样做。根据我的编程经验(擅长低级C算法和高级C图形用户界面设计),感觉很好。

其次,我不确定该怎么做。我刚刚在VS2005中构建了一个解决方案,它从C应用程序调用了一些(extern"c")dll函数。为了确保我能做到这一点,我在dll中写入了一些全局变量,并从中读取:

测试h

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

测试程序

1
2
3
4
5
6
7
8
extern int data=0;
__declspec(dllexport) void set(int num) {
    data = num;
}

__declspec(dllexport) int get() {
    return data;
}

试验室

1
2
3
4
5
[DllImport("test")]
private static extern void set(int num);

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

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

现在,我知道您也可以导出C++类,但是必须管理它吗?这是怎么回事?我走这条路对吗?

谢谢你的帮助!

*** EDIT ***

首先,感谢您迄今为止的精彩回答!我对堆栈溢出总是印象深刻…

我想我应该多了解一点,不一定是原始速度(这可以是原型和基准)。我更关心的一件事是垃圾收集器的非确定性行为。此应用程序在执行垃圾收集时不能容忍500ms的延迟。

我完全赞成在纯C中进行编码和尝试,但是如果我提前知道GC和任何其他不确定的.NET行为(?)会导致一个问题,我想我的时间会更好地花在C/C++上编码,并找出最好的C接口。


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

  • 性能(C编程指南)

  • Rico Mariani的性能博客(一个优秀的资源)

  • 调整.NET应用程序性能

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

  • C++与Java/C语言的性能
  • C++比C语言快多少?

其他条款:

  • 微基准C++、C语言和Java
  • 利用C的特性为科学计算项目提供动力
  • 使用Visual Studio探查器查找应用程序瓶颈
  • C语言对C++性能的影响


我认为你的解决方案是合理的:

  • 尽管C语言速度很快,但它永远无法与一个写得好的非托管C/C++相媲美,我自己已经开发出了高性能的应用程序,这证明了这一点,在人们发表这些声明时,人们总是会发表这样的小例子。
  • MFC或ATL用户界面编程既繁琐又缓慢,C是实现这一目标的方法,我再也不会进行MFC/ATL用户界面编程,除非被迫这样做。
  • 你的解决方案,如果你还没有解决它,被称为"混合模式",这基本上意味着你在相同的项目中组合托管的(C)和非托管的(C/C++)代码,这常常是一个麻烦,让VS项目运行起来(LNK2020错误…AGH..),但是当你找到正确的设置时,它应该工作得很好。

    唯一的缺点是,混合模式程序集必须完全信任地运行,如果可以的话,我想您知道该怎么做。

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


    对于实时应用程序:我建议C++,您将更灵活地使用内存管理,更快,甚至多平台取决于使用什么框架……

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

    我想这是解决你问题的办法!


    你需要做的第一件事就是测试你的假设。您的性能约束是什么?您希望承载应用程序的硬件类型是什么?用C语言编写一个处理核心问题的小程序,并测量它的运行速度。

    只有当你有了事实,你才能决定是否使用C/C++来管理解决方案。

    与其他评论过的人一样,我怀疑C/托管解决方案会很好地解决问题,特别是如果您使用.NET并行扩展。

    如果你最终进入C/C++路径,那么有两个选项RealIopp,即pNoCKE和COM互操作。我不相信有一种干净的方式直接从.NET访问非托管C++类;为此,您将不得不考虑实现托管/非托管C++程序集。


    我的公司做了一些非常相似的事情,虽然用的是CCD相机而不是线扫描相机。我们使用的是用于低层算法的GUI、网络通信、高级"管道"和C++/CLI。它工作得很好。您将永远无法在Windows上编写真正的实时系统,保证最大响应时间,但根据我的经验,GC是您在这里遇到的最少的问题。一方面,GC只在分配内存时运行;C/C++中的MALOC/NEW也是如此,它们也需要时间(想想内存碎片)。根据我们所做的测量,完整的GC需要10-50毫秒,并且在这段时间内不需要停止其他线程(我认为除非它们尝试分配托管内存),这对我们来说是可以的。但我不确定这些数字是否可以推广到任何类型的应用程序,您可能应该做您自己的分析来确定。

    如果您担心您的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吗?


    我同意米奇的100%。

    如果在调查了他的资源之后,你仍然觉得你需要使用一些非托管代码,你可以在C++中写一个"业务"层(或者在这种情况下,真的是一个功能层),并将你的UI写在C语言中。使用COM interop从C/托管代码调用非托管代码。

    不过,我还是觉得你不需要这么做。


    前端WPF和C++后端(PNEKEK)很快,但是当你在线程上做GUI工作时,你的GUI线程不会被你的后台代码阻塞。当你这样做的时候,你的程序看起来会更快、更轻。


    我有一个在本地C/C++和C非常低延迟系统的经验。

    • 在C/C++中,80%的处理器时间在确定性的Maloc方法中丢失,但是本机代码比MSIL代码快10X。

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

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

    那么粒度!!!!

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

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

    恭喜你的计划,保罗


    我已经用C++.NET完成了。

    由于C++.NET和C语言都被管理,所以我不明白为什么不能这么做。关键是你会怎么做。

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

    有一个叫做"InTime OS"的实时Windows解决方案,但是使用起来很痛苦。

    另一种方法是将硬实时划分为单独的DLL或库,并让C以自己的速度显示它可以做什么。实际上,用户永远无法判断你的界面是2000帧还是500帧。


    您将选择的语言不会对性能产生太大影响(假设您可以影响速度5/10%)。有什么区别的是你将使用的算法,你如何处理数据,分析你的应用程序,等等…(性能可能以10倍的比率变化)。


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