关于winapi:有没有理由在.NET上使用Win32 API(在C或C ++中)?

Is there any reason to use Win32 API (in C or C++) over .NET?

我正在完成暑期的工作,在那里我为行李扫描仪编写图形软件。一切都是在.NET或MFC中完成的,用C++进行硬件通信(我不做任何硬件的事情)。我有时使用win32 API调用(如sendmessage)来提高窗体或控件的性能。我只上了一年的CS课程(全部是C语言),但我对win32 API很着迷——它比我想象的要大得多,也比我想象的要强大。

.NET是否只是隐藏了win32 api的所有"乏味"或底层工作?最终的软件是消耗更多的系统资源还是在.NET中执行较慢?


.NET通常使开发成为EAISER。它通过提供一个系统来实现这一点,该系统使得开发人员减少了一般活动的工作量。

我喜欢在.NET中工作。在它成为可用之前,我主要使用MFC和Win32在C++中编写了一个GUI。当我切换到.NET时,我必须完全修改我的估计,因为我可以更快地完成工作!

回答你的实际问题:很少有.NET不起作用的开发场景(有些人可能会说它阻碍了发展)。这些通常涉及到硬件通信的低级使用或经过微调的COM编程。

注意,您可以在.NET中为C++开发,允许您在Win32和.NET之间进行很少的努力。(当你开发CLR时,它不是标准C++,但也不难找出差异。)

如果没有可以实际测试的实际场景,就不要考虑性能。对于.NET和C++在同一个任务上的一个有趣的性能比较,请查看博客条目(和链接!)网址:http://blogs.msdn.com/b/ricom/archive/2005/05/10/416151.aspx


Does .NET simply hide all of the"tedious" or ground level work of the Win32 API? Does the final software consume more system resources or perform slower in .NET?

是的,它试图隐藏所有乏味的细节。是的,与用C和Win32编写的类似应用程序相比,.NET应用程序通常速度较慢,而且消耗的资源可能更多。

但是,在性能上的牺牲通常是一个微不足道的代价,用来支付生产力和易维护性方面的收益。

我知道使用简单的C和纯的win32编程如此接近裸机的L33T特性可能看起来非常诱人,但我发现很难证明何时使用.NET更容易、更快。


.NET的吸引力在于它是一个更高效的开发平台。.NET框架的许多部分确实提供了win32 api的部分包装。尽管框架确实抽象了许多"乏味"的win32 api调用,但这并不能阻止我不时需要一点pinvoke。

您会发现.NETFramework涉及的开销很小,并不是像C或C++那样高效,但通常是在生产率和效率之间进行权衡。单个应用程序的需求将决定哪个更重要。在许多软件中,要求是"足够高效",并且可能完全适合.NET开发。


对于你的问题,简单的答案是"否"、"是"和"不一定",按这个顺序排列。也就是说,.NET所做的不仅仅是"隐藏"win32 api,它在某些情况下对其进行包装,在其他情况下对其进行扩展,在其他情况下完全忽略它。

用.NETFramework开发的软件通常会消耗比精益和平均手工编码的组件更多的资源(理论上)是由专家生产的,但在许多情况下,C或C++开发人员将使用与.NETFramework一样重的框架和工具包,差异将是一种清洗。另一个需要考虑的问题是,现在一个程序是否会消耗一些额外的KB内存通常是无关紧要的。没有人注意到。如果在.NET(或任何其他技术)中开发的好处大于风险,那么这是一个更好的选择。只有你能根据你的特殊情况来判断。

至于"性能",这是一个非常大的类别,但是由于.NET代码是编译成机器语言的(没有解释),所以通常没有什么区别。同样,硬代码程序集程序员可能会击败它,但是应用您的成本效益分析来确定它是否值得您使用。


.NET旨在隐藏win32 API的乏味细节。它在某些方面取得了成功,但在其他方面却失败了。如果你写的大部分内容都与微软所努力支持的内容相吻合,那么它就可以很好地成功。如果您离开到"处女地",您可能会完全失去优势,甚至会导致大量额外的工作,与直接使用win32的本机代码相比。

产生的软件(基本上总是)比本机代码消耗更多的资源。唯一真正的问题是它使用了多少内存,运行速度有多慢,等等。

不幸的是,这些问题很难回答。速度可以是从本质上相同到8倍左右。内存使用率始终较高(例如,至少为2倍,通常为3-5倍)。一个有趣的点是,垃圾收集在速度和内存消耗之间进行了权衡(更频繁地运行GC会降低内存使用率,而牺牲更多的CPU时间)。因此,执行时间与CPU速度同样取决于内存可用性。

有趣的是,我个人做的第一件事是.NET移植一个C++程序,我知道它有内存泄漏(我甚至知道它是和大致如何修复它,但实际上这样做会有很多工作)。移植到.NET并不需要很长时间(代码不多)。好消息是记忆泄漏消失了。坏消息是,正如我所能想象的那样,泄漏的C++代码将不得不连续运行一年以上,以便使用与启动时所需的.NET版本一样多的内存。


你提到的都是"分层"在win32之上,是的。Win32是您可以用Windows以编程方式使用的最低级别之一。在我看来,学习win32非常有益。

几乎所有的事情都是基于它的。这就像学习寄存器如何在CPU上工作,而不是作为一个黑盒。

我认识的所有真正优秀(专业)的Windows程序员,都非常了解它。

由CharlesPetzold编写的编程窗口几乎是win32和imo的圣经,编写和执行都很好。

顺便说一句,我认为任何一个内心和头脑中都是"工程师"的人总是需要知道事情是如何运作的。我觉得这是件好事。


.NET让您在学习时更快地开始学习,尤其是在使用可视化界面构建表单时。这在一段时间内很有吸引力,但根据我的经验,你最终会发现一些局限性。

欺骗:

1-要求客户端计算机上存在相应的.NET框架版本,这并不总是得到保证。

2-3D图形应用程序出现问题,不再支持.NET DirectX。(我认为Slimx引擎可以解决这个问题,但你还是有点卡住了)。

3-您的3D应用程序可能无法在更新版本的Windows上运行而不需要返工,或者可能没有解决方案,请参见2。(我觉得这很难)

我已经学习了一段时间了,虽然开始学习很困难,但它确实感觉更强大、更精简。

欺骗:

1-您必须在项目中处理头文件,这需要一些时间让初学者理解。有一种非常具体的方法来处理这些问题,因为编译器是"一次通过",事情的顺序很重要。

2-win32 api更像是脚本式的,所有东西都或多或少地位于一个通用的名称空间中,这个大列表很难浏览。

3-在成员的自动完成显示上没有提示/描述,因此您必须花费数周时间来查看所有不同成员的文档。

4-没有像.NET那样的自动"回调"(即单击按钮),您必须通过由"wndproc"函数处理的"messages"来处理Windows元素。这需要一些时间让你的头脑清醒过来,特别是如果你来自.NET。同样,您需要大量的文档来确定您需要什么消息名称和参数。这种模式本身并不是问题,但它使您很难将实际应用程序与Windows GUI设计分开。

5-同样,由于Windows元素通过"消息"进行通信,因此您无法获得与实际成员函数相同的明智或描述性的自动完成选项。"请参见此伪代码:

button.text="abc"; //in this case you understand the possible options

VS

SendMessage(button_hwnd, BN_SETTEXT,"abc", 0); //need to see MSDN/StackOverflow

6-不自动取消对象内存分配。但我认为这还不错。C++类有一个~~()名析构函数,当实例被销毁时,可以释放事物。我还尝试为在运行时实例化的成员使用动态数组,这有助于实际保持有序并处理实际的分配过程。pseudocode:

class game{

std::vector(ghost) ghosts;

}

update{

ghosts.pushback(); //add one, etc

ghosts.erase(position); //any element can be killed off. this is pretty good

}

~game(){ //

~ghosts(); //deallocates array

}

所以到目前为止,我看到的是您必须更加小心,并且要有足够的结构来防止内存泄漏,否则我不会让手动释放成为一个问题。

关于可移植性,我认为如果应用程序被很好地封装,那么移植到其他平台就不太难了。依靠.NET框架是不值得的,它讽刺地破坏了可移植性本身。但每个人的里程数当然各不相同。

但是,不管缺点是什么,到目前为止我对win32很满意,我已经花了大约2个月的时间学习,并且我已经为Windows控件构建了自己的包装器,因此更容易以编程方式构建和与Windows窗体交互。

我也在窗体上运行irllicht 3D引擎,它似乎可以在多台具有不同版本Windows的计算机上完美运行。看到可执行文件在任何(Windows)计算机上运行而没有依赖项或安装,真是太好了。

程序加载速度更快,大小似乎更小。不管表现如何,我认为现在阿法克没有什么大的优势。

我认为微软应该为API编写一些简单的包装器,以及一些很好的示例和模板项目,而不是使用整个庞大的.NET路线。

只要我0.02美元

编辑:我理解MFC包装了一些功能,但我读过它增加了一些开销,而且它还没有真正流行起来。希望有人能加上这个,因为我还没有真正玩过。哦,这是不是值得学习微软基金会(MFC)类现在?


我把答案放在一件事上:C++是ISO标准。C是微软的专有语言。

如果你想通过Windows扩展你的技能,ISO C & C++将会让你看到更多。

.NET有一个大的框架-但是如果你知道去哪里看,有一个巨大的LGPL和(如果你和它兼容的话)GPL开源软件,用于C++C++。Boost正在成为一个拥有.NET提供的大部分(非图形用户界面)功能,但却是跨平台标准的大型库。

这就是说,如果你不介意出卖你的灵魂,把你的事业献给一家公司持续的成功…C/.NET有两个很大的奖金,而Win32 API没有提供:

  • 很难编写不泄漏的C++代码。尽管我讨厌垃圾收集的想法,但它是有效的。
  • WPF是微软自XP以来为用户界面开发所做的最好的事情。它们看起来就像普通的Windows控件:按钮、文本框、列表视图,这是本机的win32应用程序所获得的,但在其保护下,它们支持无闪烁的绘制,具有阿尔法感知功能,并且可以进行动画和蒙皮。