在使用C++开发Win32应用程序时与使用C#开发.NET应用程序相比有哪些优势?

16

我学习了使用Visual C++和Win32 API编写Windows程序。如今,似乎大多数应用程序都是使用C#的.NET开发的。我了解到,在本机代码和托管代码之间的大多数情况下,性能差别不大。因此,我想知道,如果我今天要开始编写一个新的桌面应用程序,除了我更熟悉C++之外,是否还有其他原因要选择非托管C++而不是.NET呢?是否仍然存在使用C++和本机代码的某些优势?或者这种方法在Windows平台上已经被.NET取代了吗?

当然,我知道编写低级设备驱动程序和类似程序的人不会使用.NET。我是指客户端应用程序,它们不直接调用硬件。


如果在Win32和.Net之间做决定...选择.Net吧。有几个人抱怨他们的平台没有.Net...但是如果你是为Win32编写代码,跨平台就不是问题。 - Matthew Whited
3
我仍然经常使用C++ Win32进行开发,包括全新的应用程序。我们大部分的程序都是图形化的,很少使用固定的UI函数。我发现那些诅咒非托管内存的人通常只是在重复他们听到的话,并没有真正经历过C++。为了优化某些算法,我更喜欢“接近硬件”。另外,我要纠正一个误解——Win32的学习曲线比.NET和C#要低(前提是您有C++的经验)。请参见http://www.charlespetzold.com/pw5/index.html。+Win32可以在所有Windows操作系统上轻松安装/运行。 - Jeff
抱歉,但我很少看到.NET应用程序在实际中使用。今天大多数的Windows程序都是使用Win32API/MFC/Delphi/C++Builder/wxWidget/Qt编写的。 - dns
9个回答

18

对于小型可下载应用程序而言,最重要的一点是本地代码不需要.NET运行时。虽然宽带变得越来越普及,但远非所有人都拥有它。

有些人可能会失望地发现,您的2MB应用程序实际上需要另外20MB的框架下载和麻烦的安装过程才能运行。如果他们不确定自己是否真的需要您的应用程序,他们可能会在尝试之前就将其删除并转向竞争产品。


5
我希望我可以多次点赞这个评论。当我想尝试一个新应用程序,而它要求我安装我之前未曾安装过的运行时环境时,我会立即转向其他选择。 - Joe Pineda
你多久安装一次新版本的.NET运行时或JRE?我想我在2008年8月安装了.NET 3.5SP1。 - olli-MSFT
5
Olli:你是一名开发人员,这使你成为计算机用户的精英。除非你的客户也是开发人员(尤其是那些几乎不使用计算机的经验不足的用户),否则约一半的客户可能没有安装所需的运行时。 - Adrian Grigore
可以使用引导程序框架,但这会将您的2mb应用程序变成20mb应用程序。好处是用户不知道他们正在安装框架。 - Steven Evers
作为用户,我希望安装程序可以在必要时为我下载和安装框架,以避免原始下载文件过大。这样,如果我已经拥有框架,我就可以更快地下载应用程序。但是,这仍然远非完美。本地应用程序在这里绝对更好。 - Adrian Grigore
有时候我需要编写一个小工具,以便在尽可能多的机器上运行。我倾向于使用C++来完成这个任务。当.NET出现时,我希望使用最低版本的.NET是实现这些工具的好策略,但事实上并不是这样的——.NET 1.0/1.1已经过时了,而且新版Windows默认情况下没有安装.NET 2.0。最终,我确信C++是最好的选择,但有时候我因为懒惰而选择.NET 3.5,特别是当某个工具在.NET中更容易编写时(我知道代价是它难以或者无法在旧机器上使用)。 - Andrzej Martyna

14
  • 性能(某些情况下,例如图形)
  • 内存占用(正如Mancuso所说)
  • 使用现有库
  • 无需运行时环境
  • 更精细的控制

仅列举了一些。

然而,您可能还想从相反的角度来看这个问题,以公平评估使用哪种语言。

此外,您可以使用C++/CLI来合并本机和.net代码。


8

如果您的应用程序需要在没有安装的情况下运行(即,如果您不能或不应该像安装.NET框架那样做),则不能保证.NET已经在Windows机器(Vista之前的版本)上安装好。许多实用程序可以归入此类别。


7
我建议所有桌面应用程序都使用托管代码进行编写,.NET/C# 是一个很好的平台。
我的理由如下:
1. 性能损失可以忽略不计。如果您不相信,请搜索基准测试结果。更重要的是代码本身。您可以在 C++ 或 .NET/C# 中编写 O(n^m) 算法。JIT 引擎现在非常成熟。
2. 在单元测试、模拟和重构方面,非托管 C++ 存在主要缺点。它非常繁琐和不灵活。反射允许托管代码使这些事情变得非常方便。
3. 部署是一个小问题。但是,创建一个检查必要的 .NET 前提条件并自动安装它们的设置是易如反掌的。
4. 编译速度更快,没有链接器!即使在编辑代码时也会在后台发生编译。
5. .NET 库支持比 STL、MFC 和 boost 更好、更干净。
6. 没有头文件和宏。它们只会引起错误。
7. 安全性!再见缓冲区溢出、坏指针、未初始化变量...
8. 异常。.NET 中有清晰的异常层次结构。C++ 异常混乱不堪。

1
与事实相去甚远的是,使用托管环境会带来巨大的性能损失。对于内存管理几乎没有任何控制权,这对于需要实时性能(如视频游戏)的应用程序来说是一场灾难。托管解决方案通常最适合商业应用程序。 - James
1
而且你被困在只能在Windows上运行的解决方案中。对于所有的Mac用户来说太糟糕了... - user52875
1
@James,毫无疑问,C++在视频编解码器、视频游戏和实时场景方面有其应用。但对于桌面应用程序、Web应用程序、商业应用程序等等,绝对不是最佳选择。 - olli-MSFT
2
@wdu,编写一个可移植的本地C/C++应用程序是一门黑魔法。这需要大量的努力。使用mono/.NET和Java实现相同的目标会更容易。 - olli-MSFT
2
我同意詹姆斯的观点。.NET应用程序的内存开销非常大。看看Qt(现在具有LGPL)作为一个良好的非托管跨平台解决方案。 - Nick
显示剩余5条评论

2

内存占用。但是,除非您在为内存严重不足的机器开发应用程序,否则这对于大多数应用程序来说实际上不应该成为问题。


2
.NET倾向于“独占”内存并且除非可用内存低于阈值,否则不会将其释放回操作系统。如果您的应用程序同时运行的实例很少,并且大部分资源都用于它,则这是可以接受的。在其他情况下,这将是一场灾难。 - Joe Pineda

2

如果你可以接受依赖于堆栈,就选择.NET。它现代、优雅、强大,因此开发速度更快。

但要意识到你的应用程序会受限于它——语言和框架,在预见将来可能想要摆脱它的情况下,最好三思而后行。

Win32虽然老旧笨重,但在几乎所有Windows版本上均可工作,而且你的代码可以使用简单易懂的C/C++编写,具有可移植性。


2

+1 是因为不需要在目标机器上安装.NET包/程序。这仍然是一个很大的问题。

当所有机器都有Mono或.NET时,这就不是那么大的问题了。


0

.Net程序也有支持寿命,而本地程序则没有。本地程序可以在不需要更新的情况下跨越多年运行在不同的操作系统上。

.Net程序可能会受到糟糕的.Net配置的影响,本地程序仍然继续运行,几乎不会受到操作系统更新的影响。

.Net程序启动缓慢,感觉迟钝,原生程序启动快速,运行迅速。

.Net必须编码为最低公共分母(最广泛使用的框架版本),本地编译所有代码到应用程序-所以使用您想要的东西。

使用Delphi进行Native开发,而不是C ++。 .Net部分基于Delphi RAD和Java后端。


0

我可以想到的有两件事。

  1. 知识产权保护。对于某人来说,反向工程Unmanaged C++应用程序要难得多。Managed .Net或Java应用程序可以被轻松反编译,但这不适用于Unmanaged C++。

  2. 速度。C++更接近硬件,并且具有比其他评论提到的更小的内存占用。这就是为什么大多数视频游戏继续使用C++和内联汇编的原因。


比较苹果和香蕉。C++是一种多平台语言,可用于创建针对.NET环境的代码。这个应用程序可以像c#/CLR或Java/JVM一样轻松地反编译。然后,如果我记得正确,GCC可以将Java编译为本机代码,因此这一点无关紧要。 - Joe Pineda
实际上完全不是无意义的,这完全取决于你使用哪个编译器。如果代码编译为托管代码,则您的观点是正确的。但是,如果您将其编译为非托管代码,则我的观点仍然成立。 - James
2
相比之下,托管代码的混淆技术并不是一种很好的保护措施。你有没有试过将本地代码反汇编回可工作的C++代码?相信我,这比逆向工程托管应用程序要难得多,因为现在有许多免费的工具可以做到这一点。 - James
我希望我能编辑我的评论。我的意思是现在有许多免费的工具可以做到这一点。因此,如果您想编写具有更强代码保护的内容,肯定有优势。 - James

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接