【问题标题】:Is there any reason to use Win32 API (in C or C++) over .NET? [closed]是否有任何理由在 .NET 上使用 Win32 API(C 或 C++)? [关闭]
【发布时间】:2010-08-18 17:35:02
【问题描述】:

我正在完成我的暑期工作,为我们的行李扫描仪编写图形软件。一切都在 .NET 或 MFC 中完成,使用纯 C++ 进行硬件通信(我不做任何硬件的事情)。我有时会求助于 Win32 API 调用,例如 SendMessage 来提高表单或控件的性能。我只上了一年的 CS 课程(全部用 C 语言),但我对 Win32 API 很着迷——它比我想象的更大更强大。

.NET 是否只是隐藏了 Win32 API 的所有“乏味”或底层工作?最终的软件是否会消耗更多系统资源或在 .NET 中执行速度较慢?

【问题讨论】:

标签: .net winapi api


【解决方案1】:

.Net 通常使开发更容易。它通过提供一个系统来做到这一点,该系统使开发人员的常见活动减少了工作量。

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

回答您的实际问题:在一些不太常见的开发场景中 .NET 没有帮助(有些人可能会说它会妨碍您)。这些通常涉及硬件通信的低级使用或微调的 COM 编程。

请注意,您可以使用 C++ 为 .NET 进行开发,让您可以轻松地在 Win32 和 .NET 之间进行切换。 (当您开发到 CLR 时,它不是标准的 C++,但也不难发现差异。)

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

【讨论】:

    【解决方案2】:

    .NET 是否简单地隐藏了 Win32 API 的所有“乏味”或底层工作?最终的软件是否会消耗更多系统资源或在 .NET 中执行速度较慢?

    是的,它试图隐藏所有繁琐的细节。是的,.NET 应用程序通常比用 C 和 Win32 编写的类似应用程序更慢,并且可能消耗更多资源。

    但性能上的牺牲通常是为提高生产力和易于维护性所付出的微不足道的代价。

    我知道使用简单 C 和纯 win32 进行如此接近于裸机的编程的 l33t 因素可能看起来很诱人,但我发现很难证明使用 .NET 会更容易和更快很多倍.

    【讨论】:

    • 除非您正在调整所有 C++ 代码的性能,否则“.NET 应用程序通常会更慢”的说法具有高度误导性。在应用程序的首次运行期间,或在重新启动后首次加载任何 .NET 应用程序期间,您可能会看到这一点。但后来,C++ 和 .NET 处于同等地位——开发人员的技能决定了应用程序是否快速。 (而且 .NET 可以让技能较低的人更容易开发更快的应用程序。)
    • 我不知道,约翰。我没有任何性能基准来支持我的主张,相反,我做了一个在我看来是合理的假设:.NET 提供的易用性和精心设计的抽象将通过一些性能损失来弥补.我是第一个承认这种假设的性能下降在 99% 的情况下可以忽略不计或几乎不存在的人,但它仍然存在。我认为我们在原则上基本上是一致的,但在细节上分裂头发:)
    • 也许吧。检查我的答案中的链接,看看这是否会改变你的看法。
    【解决方案3】:

    .NET 的吸引力在于它是一个生产力更高的开发平台。 .NET 框架的许多部分确实提供了 Win32 API 的部分包装器。尽管该框架确实抽象出许多“乏味”的 Win32 API 调用,但这并不能阻止我不时需要一点 PInvoke。

    您会发现 .NET 框架确实需要一些开销,并且严格来说不如 C 或 C++ 的效率高;但是,通常要在生产力和效率之间进行权衡。个别应用程序的要求将决定哪个更重要。在很多软件中,要求是“足够高效”,并且可能完全适合.NET开发。

    【讨论】:

    • 注意通用性能声明。 .NET 中的基本、首次尝试代码可能比类似的 C++ 代码更快,甚至已经对其进行了一些性能调整。 (查看我的答案中的链接了解一些细节。)
    • @John:观点很好。这就是为什么我选择了“严格来说不如 C 或 C++ 的效率”这样的措辞。我认为这在其应用中非常不通用。
    • 查看stackoverflow.com/questions/138361/how-much-faster-is-c-than-c 可能会有所帮助,其中包含有关 C 和 C# 之间一般性能比较的讨论。正如@John 所观察到的,可衡量的性能差异并不普遍,但我发现在实践中它们确实经常存在。
    【解决方案4】:

    对您的问题的简单回答是“否”、“是”和“不一定”,依次为“否”、“是”和“不一定”。也就是说,.NET 不仅仅“隐藏”了 Win32 API,它在某些情况下封装它,在其他情况下扩展它,而在其他情况下完全忽略它。

    使用 .NET 框架开发的软件通常比专家可以(理论上)生成的精益和平均的手工编码程序集消耗更多的资源,但在许多情况下,C 或 C++ 开发人员将使用框架和与 .NET 框架一样重的工具包,不同之处将是一个洗涤。另一件要考虑的事情是,现在程序消耗一些额外的内存通常并不重要。没有人注意到。如果使用 .NET(或任何其他技术)进行开发的好处大于风险,那么它是一个更好的选择。只有您可以根据您的具体情况来判断。

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

    【讨论】:

      【解决方案5】:

      您提到的所有内容都是在 Win32 之上“分层”的,是的。 Win32 是您可以在 Windows 中以编程方式工作的最低级别之一。在我看来,学习 Win32 是非常有益的。

      几乎所有东西都基于它。 (那个和 COM。)这就像学习寄存器如何在 CPU 上工作,而不是它是一个黑盒。

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

      Programming Windows by Charles Petzold 几乎是 Win32 和 IMO 的圣经,编写和执行都很好。

      顺便说一句,我认为任何“内心深处的工程师”和头脑中的工程师总是需要知道事情是如何运作的。我认为这是一件好事。

      【讨论】:

      • 为了清楚起见,我并不是说不要学习 .Net。如果您愿意,请这样做。我只是评论学习Win32。
      • 当然不是。我在高中时用 VB 做了一点 .NET,现在我在 C# 中做了很多工作。它很棒而且非常高效,但我对自己学习 Win32 API 并编写一些简单的程序很感兴趣。当我对 Win32 足够熟悉时,我想编写一个小型 IRC 客户端来满足我的基本需求(我不喜欢为其他客户端使用附加组件)。
      【解决方案6】:

      .NET 旨在隐藏 Win32 API 的繁琐细节。它在某些方面成功了,但在其他方面却失败了。如果您编写的大部分内容都与 MS 试图支持的内容非常吻合,那么它会非常成功。如果你进入“处女地”,你可能会完全失去优势,甚至比直接使用Win32的原生代码要多做大量的工作。

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

      不幸的是,这些很难回答。速度可以是基本到慢 8 倍左右的任何地方。内存使用率一直高很多(例如,至少 2 倍,通常是 3-5 倍。有趣的一点是垃圾收集在速度和内存消耗之间进行了权衡(更频繁地运行 GC 会以降低内存使用量为代价)使用更多的 CPU 时间)。因此,执行时间取决于内存可用性和 CPU 速度。

      有趣的是,我个人使用 .NET 做的第一件事就是移植一个我知道存在内存泄漏的 C++ 程序(我什至知道它是不是以及大致如何修复它,但是实际上这样做会做很多工作)。移植到 .NET 并没有花很长时间(代码不多)。好消息是内存泄漏消失了。坏消息是,据我所知,泄漏的 C++ 代码必须连续运行一年多才能使用 .NET 版本启动所需的内存。

      【讨论】:

      • 最后一段与我使用 .NET 的经历非常相似。我编写了一个程序来查看和搜索日志文件,它使用了大量的内存。一位同事几年前用 C++ 编写了一个非常相似的程序,它只使用了一小部分内存。我的程序在处理 60MB 的文本文件时会达到 200MB,如果将整个文件加载到编辑控件中,他的程序会达到 70-80MB。
      【解决方案7】:

      .NET 让您在学习时更快上手,尤其是在使用可视界面构建表单时。这在一段时间内非常有吸引力,但根据我的经验,您最终会发现一些限制。

      缺点:

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

      2- 3D 图形应用程序存在问题,已停止支持 .net directX。 (我认为 SlimX 引擎可以解决这个问题,但你还是有点卡住了)。

      3-您的 3D 应用程序可能无法在较新版本的 Windows 上运行而无需返工,或者可能没有解决方法,请参阅 #2。 (我发现这很难)

      我学习 Win32 已经有一段时间了,虽然入门比较困难,但感觉确实更强大、更精简。

      缺点:

      1-你必须在你的项目中处理头文件,这对于初学者来说需要一些时间来理解。由于编译器是“一次性”的,而且事情的顺序很重要,因此有一种非常具体的方式来处理这些。

      2-win32 API 更严格,所有内容都在一个或多或少的通用命名空间中,大列表很麻烦。

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

      4-没有像 .NET 中那样的自动“回调”(即 On_button_click),您必须通过“wndproc”函数处理的“消息”来处理 Windows 元素。这需要一些时间来理解,尤其是如果您来自 .NET。再次,您必须翻阅大量文档来确定您需要哪些消息名称和参数。 这种范式本身不是问题,但它使您很难将您的实际应用程序与您的 Windows gui 设计分开。

      5-再次,由于 Windows 元素通过“消息”进行通信,因此您无法获得与实际成员函数一样的合理或描述性自动完成选项 看到这个伪代码:

      button.text="abc"; //在这种情况下,您了解可能的选项

      SendMessage(button_hwnd, BN_SETTEXT, "abc", 0); //需要看MSDN/StackOverflow

      6-不会自动取消分配对象内存。但我认为这还不算太糟糕。 c++ 类有一个 ~name() 析构函数,当实例被销毁时,您可以在其中释放事物。 我还尝试为在运行时实例化的成员使用动态数组,这有助于实际有序并处理实际的分配过程。 伪代码:

      类游戏{

      std::vector(ghost) 幽灵;

      }

      更新{

      ghosts.pushback(); //加一个,等等

      ghosts.erase(位置); //任何元素都可以被杀死。这个不错

      }

      ~game(){ //

      ~鬼(); //释放数组

      }

      所以到目前为止我所看到的是,您只需要更加注意和结构化以防止内存泄漏,否则我不会让手动释放成为问题。

      关于可移植性,我认为如果应用程序封装良好,那么移植到其他平台应该不会太难。依赖 .NET 框架是不值得的,具有讽刺意味的是,它本身就破坏了可移植性。 但是每个人的里程当然会有所不同。

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

      我还在窗体上运行 irllicht 3D 引擎,它似乎可以在具有不同 Windows 版本的多台机器上完美运行。很高兴看到可执行文件在任何 (Windows) 机器上运行而无需依赖或安装。

      程序加载速度更快,看起来更小。然而,在性能方面,我认为这些天 AFAIK 并没有太大的优势。

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

      只要我的 0.02 美元

      编辑:我知道 MFC 封装了一些功能,但我读过它会增加一些开销,而且它并没有真正流行起来。希望有人可以补充这一点,因为我还没有真正玩过它。 哦,这里 [Is it worth to learn Microsoft Foundation Classes(MFC) Nowadays?

      【讨论】:

      • “MFC [...] 还没有真正流行起来。” - MFC 于 1992 年发布,随 Visual Studio 的每个版本(除了 Express Editions )。它已获得近 25 年的支持。 “我相信 Microsoft 应该为 API 编写一些简单的包装器” - 如果你愿意,他们确实做到了,以 MFC 或 Windows Forms/.NET 的 BCL 甚至 Windows 运行时的形式轻巧的东西。
      • 请在这里停止争论。如果你想继续这个讨论,我建议你去聊天。
      【解决方案8】:

      我的回答基于一件事:C++ 是一个 iso 标准。 C# 是一种专有的 Microsoft 语言。

      如果您想将自己的技能扩展到 Windows 之外,iso C 和 C++ 可以让您走得更远。

      .NET 有一个庞大的框架——但如果你知道在哪里可以看到有大量的 lgpl 和(如果你与它兼容的话)为 C 和 C++ 编写的 gpl 开源软件。 boost 正在成为一个庞大的库,它具有 .NET 提供的大部分(非 GUI)功能,但采用跨平台标准。

      也就是说,如果您不介意出卖自己的灵魂并将自己的职业生涯奉献给一家公司的持续成功... C# / .NET 有两个 Win32 API 没有提供的重大好处:

      • 很难编写不泄漏的 c++ 代码。尽管我讨厌垃圾收集的想法,但它是有效的。
      • WPF 是微软自 XP 以来为 UI 开发提供漂亮东西的地方。它们看起来就像普通的 Windows 控件:按钮、文本框、列表视图,这些都是本机 Win32 应用程序所获得的,但实际上它们支持无闪烁绘制、Alpha 感知,并且可以设置动画和皮肤。

      【讨论】:

      • 附言。我敢肯定,微软至少和一家成立于 1850 年的公司一样稳定,每天处理数百亿美元的信贷。 en.wikipedia.org/wiki/Lehman_Brothers 等等。他们破产了。
      • 不得不投反对票,因为研究太差,而且充满了虚假信息。 C# 于 2006 年正式发布为 ISO/IEC 23270:2006 标准。它可以在 Microsoft Windows 之外使用(例如,在 2004 年开始的Mono 项目中)。今天,您可以编写 C# 代码来面向 Windows、Android 和 iOS。至于无闪烁绘画:这也是桌面窗口管理器的一个功能,首先在 Windows Vista(2006/7 发布)中提供。从那以后,本机窗口默认情况下是双缓冲的。顺便说一句,WPF 是随 Vista 一起引入的。
      猜你喜欢
      • 2017-06-05
      • 2010-10-23
      • 2010-11-03
      • 2010-11-05
      • 1970-01-01
      • 2011-06-21
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      相关资源
      最近更新 更多