学习低级WinAPI编程还有意义吗?

55

将所有C#管理的快感放弃,回到Petzold的《Windows编程》中,尝试使用纯WinAPI编写代码,这样做有意义吗?

从中可以学到什么?它不是太过时而无用吗?


2
顺便提一下,它是 Petzold 而不是 Petzhold。 - MarkJ
Web应用将取代Windows应用程序。 Web应用通过浏览器工作。 浏览器是一个Windows应用程序。 - Sesh
消息泵是编程世界的核心。 - GalacticJello
22个回答

65

这个问题涉及到宗教信仰的层面 :) 但我还是会分享我的想法。

我认为学习Win32 API是有价值的。大多数GUI库(托管或非托管)都需要调用Win32 API。即使是最全面的库也无法覆盖API的100%,因此总会有一些需要通过直接API调用或P/Invoke来填补的空白部分。一些包装器的名称与基础API调用的名称相似,但这些名称并不是完全自解释的。因此,了解底层API以及其中使用的术语将有助于理解包装器API以及它们实际执行的操作。

此外,如果您了解框架所使用的底层API的性质,则在特定情况下选择哪个库功能将更加明智。

干杯!


23

我在学习Win32 API之前,多年来一直坚持使用标准的C/C++,坦率地说,“学习Win32 API”这部分并不是我生命中最好的技术经验。

一方面,Win32 API相当酷。它就像C标准API的扩展(当您可以使用CreateFile时,谁需要fopen)。但我猜UNIX/Linux/WhateverOS也有同样的小玩意函数。无论如何,在Unix/Linux中,它们拥有“一切都是文件”。在Windows中,他们有“一切都是...窗口”(不开玩笑!请参见CreateWindow!)。

另一方面,这是一个遗留的API。您将处理原始的C和疯狂的C。

  • 比如说,通过 void * 指针传递自身大小的结构到一些 Win32 函数中。
  • 消息传递也可能非常令人困惑:将 C++ 对象与 Win32 窗口混合使用会导致非常有趣的 鸡生蛋还是蛋生鸡 问题(当你在类方法中写下一种 delete this ; 的时候,会有很有趣的时刻)。
  • 当你更熟悉对象继承时,必须子类化 WinProc 是令人头疼且不太理想的。
  • 当然,还有那些让你用头敲键盘的 "为什么他们要这样做??" 的时刻,因为有些人认为编写一个 API 来改变 "Window" 的颜色,而不是通过更改其属性来进行,向其父窗口询问更加合乎逻辑。
  • 等等。
在最后一手牌(三手牌???)中,请考虑到一些使用遗留API的人正在使用遗留代码风格。当你听到"const is for dummies"或"我不使用命名空间,因为它们会降低运行时速度",甚至更好的"嘿,谁需要C++?我用自己的面向对象的C编程!!!"(真的...在一个专业环境中,结果相当惊人...),你会感到一种只有被判刑的人才会感到的恐惧guillotine
所以......总的来说,这是一种有趣的经历。
编辑
重新阅读这篇文章后,我发现它可能被看作是过于负面的。它并不是。
有时了解事情在幕后是如何工作的是有趣的(以及令人沮丧的)。你会明白,尽管存在巨大(不可能的?)限制,Win32 API团队做了很出色的工作,确保从你的“olde Win16程序”到你的“last Win64过顶应用程序”,过去、现在和未来都可以协同工作。
问题是:你真的想要吗?
因为花费几周时间去完成可以在其他更高级别和/或面向对象的API中完成(并且完成得更好)的事情可能会让你失去动力(现实生活经验:Win API需要3周,而在其他三种语言和/或库中只需要4小时)。

无论如何,你会发现雷蒙德·陈的博客非常有趣,因为他拥有对Win API及其多年演变的内部视角:

https://blogs.msdn.microsoft.com/oldnewthing/


你不需要使用C++来使用win32api。你可以使用Python或其他不需要在执行简单任务之前进行15行内存管理的东西。 - jle
5
@jle:是的,但通过Python使用Win32 API就像通过Java或C#使用Win32 API一样:有人已经为您编写了包装器。此外,我希望您不要使用Win32编写GUI,因为即使使用Python,这也很麻烦。最后,这个问题没有提到Python(或其他脚本语言),也没有“python”标签,所以... - paercebal

16

当然。如果没有人了解底层,谁会更新和编写高级语言呢?另外,当你理解底层知识时,你可以在高级语言中编写更有效率的代码,并且可以更有效地进行调试。


16
本地API是“真正”的操作系统API。 .NET库(除了少数例外)不过是它们的一个花哨的包装器。所以,是的,我会说任何能够理解.NET及其所有复杂性的人都可以理解相对平凡的事情,例如在没有中间人的情况下与API通信。
试着从托管代码中进行DLL注入。这是不可能的。你将被迫为此编写本地代码,用于窗口调整,用于真正的子类化和其他十几个事情。
所以,是的:你应该(必须)了解两者。
编辑:即使您计划使用P / Invoke。

11

假设你正在构建针对Windows的应用程序:

  • 了解系统更低级别的工作原理,以及您的代码如何与其交互(即使是间接地),和在更高级别的抽象中无法使用但可用的其他选项,这将有助于您获取更多信息。
  • 有时,您的代码可能不够高效,高性能或精确。
  • 然而,在越来越多的情况下,像我们这样从未学习“非托管编码”的人也可以成功地完成所需的编程,而无需“学习”Win32。
  • 此外,还有很多网站提供工作示例、代码片段甚至完整的源代码,您可以“利用”(借用、抄袭——但请检查您是否遵守任何重复使用许可证或版权!)填补.NET框架类库(或您可以下载或许可的库)无法处理的任何空白。
  • 如果您可以在不深入研究Win32的情况下完成所需的任务,并且您正在开发良好的、易读的托管代码,那么我认为掌握.NET比在两个截然不同的环境中分散你的注意力要好。
  • 如果您经常需要利用那些没有得到良好框架类库覆盖的Windows功能,那么请学习您需要的技能。
  • 我个人已经花了太多时间担心我应该理解的“其他领域”,以制作“好程序”,但还有很多受虐狂认为每个人的需求和欲望都像他们自己一样。痛苦喜欢陪伴。 :)

假设你正在为“Web 2.0”世界构建应用程序,或者对Unix和MacOS用户同样有用:

  • 坚持使用针对尽可能多跨平台环境的语言和编译器。
  • 在Visual Studio中使用纯.NET显然比Win32更好,但是针对MONO库进行开发,可能使用Sharp Develop IDE更好。
  • 您也可以花时间学习Java,这些技能将非常适用于C#编程(此外,Java代码理论上可以在具有相应JRE的任何平台上运行)。我听说过一句话,称Java更像是“写一次,到处调试”,但这可能与(甚至比)C#一样真实。

  • 9

    比喻:如果你以制造汽车为生(编程),那么了解发动机的工作原理(Win32)非常重要。


    8

    这是对任何像“即使有更高级的语言/ API Y,学习低级语言/ API X是否有意义”的问题的回答。

    是的

    你能够启动你的Windows PC(或任何其他操作系统),并在SO上提出这个问题,因为微软的几个人编写了16位汇编代码来加载你的操作系统。

    你的浏览器之所以能工作,是因为有人用C语言编写了一个操作系统内核,为所有浏览器的请求提供服务。

    它一直延伸到脚本语言。

    无论大小,都存在在任何抽象层次上编写某些东西的市场和机会。你只需要喜欢它并适合正确的工作。

    除非有更好的竞争对手处于同一级别,否则在任何抽象层面上都没有不相关的api /语言。

    另一种看待它的方式:Michael Abrash的一本书中的一个很好的例子:一位C程序员被赋予编写清除屏幕的函数的任务。由于C是比汇编更好(更高级)的抽象,程序员只知道C,并且精通。他尽了最大努力-他将光标移动到屏幕上的每个位置并清除那里的字符。他优化了循环,并确保它尽可能快地运行。但是仍然很慢...直到有人进来说有一些BIOS / VGA指令或其他东西可以立即清除屏幕。

    了解你所走的路总是有帮助的。


    8
    简单回答,是的。

    7
    是的,有几个原因:
    1).net封装了Win32代码。通常情况下,使用.net进行编程是更优秀的系统,但对底层的Win32层(现在64位代码也有了WinAPI)有一定了解可以加强您对实际情况的了解。
    2)在这个经济形势下,当你正在寻找工作时,拥有一些优势比其他人更好。一些WinAPI经验可能会为您提供这种优势。
    3)某些系统方面目前还无法通过.net框架获得,如果想要访问这些功能,您将需要使用p/invoke(请参见http://www.pinvoke.net获取帮助)。至少掌握一些WinAPI经验将使您的p/invoke开发工作更加高效。
    4)(添加)现在Win8已经存在一段时间了,它仍然建立在WinAPI之上。iOS、Android、OS/X和Linux都已经出现了,但WinAPI在未来很多年内仍将存在。

    4

    学习一门新的编程语言或技术通常有以下三个原因:
    1. 需求:你正在为构建 Web 应用程序启动项目,但你不知道 ASP.NET。
    2. 热情:你非常兴奋 ASP.NET MVC。为什么不试一试呢?
    3. 空闲时间:但是谁会有那个时间呢。

    学习新东西最好的理由是有需求。如果你需要做一些 .NET 框架无法胜任的事情(比如性能),那么 WinAPI 就是你的解决方案。在此之前,我们可以忙于学习 .NET。


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