快速的 C++ 程序,C# GUI,可能吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1247968/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Fast C++ program, C# GUI, possible?
提问by Jonathon Reinhart
I'm looking into developing an application that will process data from a line-scan camera at around 2000 lines (frames) per second. For this real-time application, I feel that C/C++ are the way to go. (It is my feeling, and others will agree that Managed code just isn't right for this task.)
我正在研究开发一个应用程序,该应用程序将以每秒 2000 行(帧)的速度处理来自线扫描相机的数据。对于这个实时应用,我觉得C/C++是要走的路。(这是我的感觉,其他人会同意托管代码不适合这项任务。)
However, I've done verylittle MFC, or any other C++ GUI. I am really getting to do C# GUIs very well, though.
不过,我已经做了非常少的MFC或任何其他的C ++图形用户界面。不过,我真的很擅长做 C# GUI。
So it seems natural to me to write the data-intensive code in C/C++, and the GUI in C#. The GUI will be used for set-up/calibration/on-line monitoring (and possibly outputting of data via UDP, because it's easier in C#.
所以对我来说,用 C/C++ 编写数据密集型代码和用 C# 编写 GUI 似乎很自然。GUI 将用于设置/校准/在线监控(并且可能通过 UDP 输出数据,因为它在 C# 中更容易。
So first, I'd like to see if anyone agrees that this would be the way to go. Based on my programming experience (good at low-level C algorithms, and high-level C# GUI design), it just feels right.
首先,我想看看是否有人同意这将是要走的路。根据我的编程经验(擅长低级 C 算法和高级 C# GUI 设计),感觉刚刚好。
Secondly, I'm not sure the right way to go about it. I just threw together a solution in VS2005, which calls some (extern "C") DLL functions from a C# app. And to make sure I could do it, I wrote to some global variables in the DLL, and read from them:
其次,我不确定正确的方法。我刚刚在 VS2005 中组合了一个解决方案,它从 C# 应用程序调用一些(extern“C”)DLL 函数。为了确保我能做到,我在 DLL 中写入了一些全局变量,并从中读取:
test.h
测试.h
int globaldata;
extern "C" __declspec(dllexport) void set(int);
extern "C" __declspec(dllexport) int get();
test.cpp
测试.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();
Calling get()
and set()
work properly (get()
returns the number that I passed to set()
).
呼叫get()
并set()
正常工作(get()
返回我传递给的号码set()
)。
Now, I know that you can export a C++ class as well, but does it have to be managed? How does that work? Am I going about this the right way?
现在,我知道您也可以导出 C++ 类,但是它必须被管理吗?这是如何运作的?我会以正确的方式解决这个问题吗?
Thanks for all your help!
感谢你的帮助!
*** EDIT ***
*** EDIT ***
First of all, THANK YOUfor your fantastic answers so far! I'm always incredibly impressed with Stack Overflow...
首先,感谢您到目前为止的精彩回答!我总是对 Stack Overflow 印象深刻......
I guess one thing I should have hit on more, was not necessarily raw speed (this can be prototyped and benchmarked). One thing that has me more concerned is the non-deterministic behavior of the Garbage Collector. This application would notbe tolerant of a 500ms delay while performing garbage collection.
我想我应该更多地了解一件事,不一定是原始速度(这可以进行原型设计和基准测试)。让我更关心的一件事是垃圾收集器的非确定性行为。此应用程序将不会是500ms的延迟容忍在执行垃圾收集。
I am all for coding and trying this in pure C#, but if I know ahead of time that the GC and any other non-deterministic .NET behavior (?) will cause a problem, I think my time would be better spent coding it in C/C++ and figuring out the best C# interface.
我完全赞成在纯 C# 中进行编码和尝试,但是如果我提前知道 GC 和任何其他非确定性 .NET 行为(?)会导致问题,我认为我的时间最好花在编码上C/C++ 并找出最好的 C# 接口。
采纳答案by Mitch Wheat
There is no reason that you can't write high performance code entirely in C#.
没有理由不能完全用 C#编写高性能代码。
Rico Mariani's Performance Blog(an excellent resource)
SO questions on the same/similiar topic:
关于相同/相似主题的 SO 问题:
Other articles:
其他文章:
回答by Nicolas Viennot
The language you'll choose will not affect much the performance (say you can affect speed by 5/10%). What will make the difference is the algorithms you will be using, how you process data, profiling your application, etc... (performance could change with a ratio of 10x).
您选择的语言不会对性能产生太大影响(假设您可以将速度影响 5/10%)。不同之处在于您将使用的算法、处理数据的方式、分析应用程序等...(性能可能会以 10 倍的比率变化)。
回答by Eric J.
I agree with Mitch 100%.
我 100% 同意米奇。
If after investigating his resources, you still feel that you need to use some unmanaged code, you can write a "business" layer in C++ (or in this case, really a functional layer) and write your UI in C#. Use COM Interopto call from C#/managed code to your unmanaged code.
如果在调查了他的资源后,您仍然觉得需要使用一些非托管代码,您可以用 C++ 编写一个“业务”层(或者在这种情况下,实际上是一个功能层)并用 C# 编写您的 UI。使用COM Interop从 C#/托管代码调用非托管代码。
Again, though, my feeling is that you will not need to do this.
不过,我的感觉是您不需要这样做。
回答by sylvanaar
For C++ you use C++/CLI - which is actually not that bad. It's a lot better than the old managed extensions.
对于 C++,您使用 C++/CLI - 这实际上还不错。它比旧的托管扩展要好得多。
To comment on performance. It really depends. How much back and forth will the there be between your C++ code and your C# code? Will you have a background thread gathering data in C++ and periodically sending that to the C# code? If you are going to be interfacing with a device, will it be using serial, USB, some API you have been given?
对性能进行评论。这真的取决于。你的 C++ 代码和你的 C# 代码之间会有多少来回?您是否有一个后台线程在 C++ 中收集数据并定期将其发送到 C# 代码?如果您要与设备连接,它会使用串行、USB 还是您提供的某些 API?
回答by Eric Smith
The first thing you need to do is test your assumption. What are your performance constraints? What sort of hardware are you expecting to host the application? Write a small program in C# that deals with the core problem and measure how fast it runs.
您需要做的第一件事是测试您的假设。你的性能限制是什么?您希望使用哪种硬件来托管应用程序?用 C# 编写一个小程序来处理核心问题并测量它的运行速度。
Only once you have the facts can you make a decision about whether or not to use C/C++ over a managed solution.
只有掌握了事实,您才能决定是否使用 C/C++ 而不是托管解决方案。
Along with others who have commented, I suspect that a C#/managed solution will do just fine, especially if you make use of the .NET Parallel Extensions.
与其他评论者一起,我怀疑 C#/托管解决方案会很好,特别是如果您使用.NET Parallel Extensions。
If you end up going the C/C++ route, then there are two options re interop, namely, pInvoke and COM interop. I don't believe there's a clean way to access unmanaged C++ classes directly from .NET; to this end, you would have to consider implementing a managed/unmanaged C++ assembly.
如果您最终选择了 C/C++ 路线,那么有两个选项可以重新互操作,即 pInvoke 和COM interop。我不相信有一种干净的方法可以直接从 .NET 访问非托管 C++ 类;为此,您必须考虑实现托管/非托管 C++ 程序集。
回答by Matthieu
For real time application: I recommend C++, you will be more flexible with memory management, faster, and even multi-platform depending on what framework is used...!
对于实时应用:我推荐 C++,你会更灵活地进行内存管理,更快,甚至是多平台,具体取决于使用的框架......!
About framework and GUI, I recommend you having a look at Qt. Qt is a great framework for C++ software development.
关于框架和 GUI,我建议你看看Qt。Qt 是一个很好的 C++ 软件开发框架。
I guess it's the solution to your problem !
我想这是您问题的解决方案!
回答by Matthieu
In my opinion your solution is a sound one:
在我看来,您的解决方案是合理的:
- Even though C# is fast it never can compete with a well written unmanaged C/C++, I have made high-performance applications myself that proves this beyond the tiny examples that people always post when someone posts these kinds of statements
- MFC or ATL UI programming is cumbersome and slow, C# is the way to go here, I NEVER will do MFC/ATL UI programming ever again, unless forced to
- 尽管 C# 速度很快,但它永远无法与编写良好的非托管 C/C++ 竞争,我自己制作了高性能应用程序,证明了这一点,超越了人们在发布此类语句时总是发布的小示例
- MFC 或 ATL UI 编程既麻烦又缓慢,C# 是这里的最佳选择,我永远不会再进行 MFC/ATL UI 编程,除非被迫
Your solution, in case you haven't figured it out yet, is called "Mixed Mode", which basically means that you combine Managed (C#) and Unmanaged (C/C++) code in the same projects, it is often a bit of a hassle to get the VS project up-and-running (LNK2020 errors..argh..) but when you find the right settings it should work just fine.
如果您还没有弄清楚,您的解决方案称为“混合模式”,这基本上意味着您将托管 (C#) 和非托管 (C/C++) 代码组合在同一个项目中,通常有点让 VS 项目启动并运行很麻烦(LNK2020 错误..argh..)但是当您找到正确的设置时,它应该可以正常工作。
Only negative thing is that mixed mode assemblies must run in Full Trust, if that's OK then I guess you know what to do.
唯一的缺点是混合模式程序集必须在完全信任下运行,如果可以,那么我想您知道该怎么做。
One other thing you might want to look at is an open source project called SWIG. SWIG takes your C/C++ code and creates a .NET assembly out of it, I have used it myself in my TM++open source project. See here for more information about SWIG http://www.swig.org/.
您可能想查看的另一件事是名为SWIG 的开源项目。SWIG 使用您的 C/C++ 代码并从中创建一个 .NET 程序集,我自己在我的TM++开源项目中使用过它。有关 SWIG 的更多信息,请参见此处http://www.swig.org/。
回答by Niki
My company does something very similar, although with CCD cameras instead of line-scan cameras. We're using C# for the GUI, network communication, high-level "plumbing" and C++/CLI for the low-level algorithms. It works quite well. You'll never be able to write a true realtime system with guaranteed maximum response times on windows, but from my experience the GC will be the least of your problems here. For one thing, the GC only runs when you allocate memory; so does malloc/new in C/C++, and they need time, too (think memory fragmentation). From the measurements we've done, a full GC takes 10-50ms and will not neccessarily stop the other threads during that time (unless they try to allocate managed memory, I think), which is ok for us. But I'm not sure if these numbers can be generalized to any kind of application, you probably should do your own profiling to be sure.
我的公司做了一些非常相似的事情,尽管使用 CCD 相机而不是线扫描相机。我们将 C# 用于 GUI、网络通信、高级“管道”和 C++/CLI 用于低级算法。它运作良好。您永远无法编写一个真正的实时系统,并保证在 Windows 上的最大响应时间,但根据我的经验,GC 将是您遇到的问题中最少的。一方面,GC 仅在您分配内存时运行;C/C++ 中的 malloc/new 也是如此,它们也需要时间(想想内存碎片)。从我们所做的测量来看,完整的 GC 需要 10-50 毫秒,并且在这段时间内不会停止其他线程(除非他们尝试分配托管内存,我认为),这对我们来说没问题。但我不确定这些数字是否可以推广到任何类型的应用程序,
If you're afraid that your GUI might break your realtime constraints, you might consider putting the actual image processing into a separate process and communicate with the GUI using pipes/sockets. Or at least keep that option in mind when you design your system, so you have it as a worst-case option, if you really run into unforseen performance problems.
如果您担心您的 GUI 可能会破坏您的实时限制,您可以考虑将实际图像处理放入一个单独的进程中,并使用管道/套接字与 GUI 进行通信。或者至少在设计系统时记住该选项,因此如果您真的遇到无法预料的性能问题,您可以将其作为最坏情况的选项。
Your second question was if you should use C++ or C# for the actual algorithms. Personally, I feel more comforatble in C++ when I write complex image processing algorithms. I think the language is better suited for the task, and there are far more numbercrunching libraries for C/C++ than for C#. But that might be a matter of personal preference. From a performance point of view, C++ has the advantage that the C++ inliner is better than the .NET JIT inliner (i.e. it can inline more of your small function calls).
您的第二个问题是您是否应该将 C++ 或 C# 用于实际算法。就个人而言,当我编写复杂的图像处理算法时,我觉得在 C++ 中更舒服。我认为该语言更适合这项任务,而且 C/C++ 的数字运算库比 C# 的要多得多。但这可能是个人喜好的问题。从性能的角度来看,C++ 的优势在于 C++ 内联程序比 .NET JIT 内联程序更好(即它可以内联更多的小函数调用)。
If you choose to use C++, I'd suggest using C++/CLI: That way, you can write C++ classes that are compiled into managed code. The C++ optimizer will optimize them, only the last compilation step to native code will be done by the .NET JIT. The big advantage is that you can directly access your .NET classes from C++/CLI, and you can easily create managed classes in C++/CLI that can be accessed from C#. You don't need to write wrapper code on both sides of the fence. (C++/CLI is a bit clunky because it contains language constructs for managed and for unmanaged programming, but if you're already familiar with unmanaged C++ and C#, you probably won't have any problems understanding it.)
如果您选择使用 C++,我建议使用 C++/CLI:这样,您可以编写编译为托管代码的 C++ 类。C++ 优化器会优化它们,只有最后一步编译到本机代码才会由 .NET JIT 完成。最大的优点是您可以直接从 C++/CLI 访问您的 .NET 类,并且您可以轻松地在 C++/CLI 中创建可以从 C# 访问的托管类。您不需要在围栏的两侧编写包装器代码。(C++/CLI 有点笨拙,因为它包含用于托管和非托管编程的语言结构,但如果您已经熟悉非托管 C++ 和 C#,那么理解它可能不会有任何问题。)
回答by Eric
I've done it with C++.NET
我已经用 C++.NET 完成了
Since both C++.NET and C# are managed I don't see why it could not be done. The point is how you will do it.
由于 C++.NET 和 C# 都是托管的,我不明白为什么它不能完成。关键是你会怎么做。
My scanner had up to 3000 lines / sec but the key strategy was to display blocks of 32 lines at a time. I didn't have hard real time requirements so I could be a little behind sometimes. If real time is very important to you, you should consider switching platform.
我的扫描仪的速度高达 3000 行/秒,但关键策略是一次显示 32 行的块。我没有严格的实时要求,所以有时我可能会有点落后。如果实时性对你很重要,你应该考虑切换平台。
There is a real time windows solution called "InTime OS" but its really painful to use.
有一个名为“InTime OS”的实时 Windows 解决方案,但使用起来真的很痛苦。
Another approach you can have is to separate the hard real time into a separate dll or library and have the C# show what it can at it's own speed. Really, the user will never be able to tell if your interface has 2000 fps or 500 fps
您可以采用的另一种方法是将硬实时分离到单独的 dll 或库中,并让 C# 以自己的速度展示它可以做什么。真的,用户永远无法判断你的界面是 2000 fps 还是 500 fps
回答by Brian
Why windows? It has horrible memory performance and worse network compared with any of the unixes out there. Specialized capture of a line sensor implies you need an appliance to handle the raw input. Consider using the right OS first which will greatly lower the other pressures you'll have to deal with (I'm am very very familiar with line scanner technologies).
为什么是窗户?与现有的任何 unix 相比,它具有可怕的内存性能和更差的网络。线传感器的专门捕获意味着您需要一个设备来处理原始输入。首先考虑使用正确的操作系统,这将大大降低您必须处理的其他压力(我对线扫描仪技术非常熟悉)。