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

时间:2008-08-08 00:29:14

标签: windows winapi

让所有C#管理的幸福回到Petzold的编程窗口并尝试使用纯WinAPI生成代码是否有意义?

可以从中学到什么?是不是太过时了有用?

22 个答案:

答案 0 :(得分:61)

这个问题接近于宗教:)但无论如何我都会提出我的想法。

我确实看到了学习Win32 API的价值。大多数(如果不是全部)GUI库(托管或非托管)都会导致对Win32 API的调用。即使是最彻底的库也不能覆盖100%的API,因此总是存在需要通过直接API调用或P /调用来插入的空白。 API调用的一些包装器名称与底层API调用具有相似的名称,但这些名称并不完全是自我记录的。因此,理解底层API及其中使用的术语将有助于理解包装器API及其实际操作。

另外,如果您了解框架使用的基础API的性质,那么您将在给定方案中应该使用哪些库功能做出更好的选择。

干杯!

答案 1 :(得分:22)

我在学习Win32 API之前已经使用了标准的C / C ++多年,而且直言不讳,“学习Win32 API”部分并不是我生命中最好的技术经验。

一方面,Win32 API非常酷。这就像C标准API的扩展(当你可以拥有fopen时需要CreateFile。但我猜UNIX / Linux / WhateverOS具有相同的Gizmo功能。无论如何,在Unix / Linux中,他们有“一切都是文件”。在Windows中,他们有“一切都是......窗口”(不开玩笑!见CreateWindow!)。

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

  • 就像告诉一个人的结构自己的大小,通过指向某个Win32函数的void *指针。
  • 消息传递也可能非常令人困惑:将C ++对象与Win32窗口混合会导致Chicken or Egg问题的非常有趣的例子(当你在类方法中编写一种delete this ;时有趣的时刻)。 / LI>
  • 当您更熟悉对象继承时,必须继承WinProc是头分裂并且不是最优的。
  • 当然,还有“为什么在这个水力压裂的世界里,他们这样做了这件事?”当你用太多的头撞到你的键盘然后回到家的时候刻在你额头上的钥匙,只是因为有人认为编写一个API来改变“窗口”的颜色更合乎逻辑,而不是改变它的一个属性,而是通过询问它的父窗口。

在最后一手(三手??? )中,考虑一些使用旧版API的人自己使用遗留代码样式。你听到“ const用于假人”或“我不使用命名空间因为它们会降低运行时速度”的那一刻,或者更好的“< i>嘿,谁需要C ++?我用我自己的面向对象的C代码编码!“(不开玩笑......在专业的环境中,结果很明显...),你会在guillotine面前感受到那种只有被谴责的恐惧。

所以...总而言之,这是有趣的体验。

修改

重新阅读这篇文章后,我发现它可能被视为过度消极。事实并非如此。

有时(或令人沮丧的)知道事情是如何工作的。你会明白,尽管存在巨大的(不可能的?)约束,但Win32 API团队确实做了很多工作,以确保从“olde Win16程序”到“最后的Win64 over-the-top应用程序”的所有内容都可以一起工作,在过去,现在和将来。

问题是:你真的想要吗?

因为在其他更高级别和/或面向对象的API中花费数周时间来完成可以完成(并且做得更好)的事情可能会非常激励(实际体验:Win API为3周,而4其他三种语言和/或图书馆的小时数。)

无论如何,你会发现Raymond Chen的博客非常有趣,因为他的内部人员对Win API及其多年来的演变有所了解:

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

答案 2 :(得分:16)

绝对。当没有人知道低级别时,谁会更新并编写高级语言?此外,当您了解低级别的东西时,您可以使用更高级别的语言编写更高效的代码,并且还可以更有效地进行调试。

答案 3 :(得分:16)

本机API是“真正的”操作系统API。 .NET库(除了极少数例外)只不过是一个奇特的包装器。所以,是的,我会说任何能够理解.NET复杂性的人都可以理解相对平凡的事情,比如在没有中间人的情况下与API交谈。

尝试从托管代码执行DLL注入。它无法完成。您将被迫为此编写本机代码,用于窗口调整,实际子类化以及其他十几项操作。

所以是的:你应该(必须)知道两者。

编辑:即使您打算使用P / Invoke。

答案 4 :(得分:11)

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

  • 了解系统的较低级别 - 它们如何工作,代码如何与它们交互(即使只是间接地),以及您在哪里有更高级别抽象中没有的其他选项,它确实可以提供信息。
  • 有时,您的代码可能无法满足您的要求的效率,高性能或精确度
  • 然而,在越来越多的情况下,像我们这样的人(他们从未学过“非托管编码”)将能够在不“学习”Win32的情况下完成我们正在尝试的编程。
  • 此外,有很多网站提供工作样本,代码片段,甚至是可以“利用”的全功能源代码(借用,抄袭 - 但请检查您是否遵守任何重用许可或版权!填写.NET框架类库(或您可以下载或许可的库)未处理的任何空白。
  • 如果您可以在Win32中完成所需的功能,而且您在开发格式良好,可读的托管代码方面做得很好,那么我认为掌握.NET将是一个更好的选择。在两个截然不同的环境中展开自己。
  • 如果您经常需要利用那些没有获得良好的Framework类库覆盖率的Windows功能,那么请务必学习所需的技能。
  • 我个人花了太多时间担心编码的“其他区域”,我认为要理解为了制作“好的节目”,但是那里有很多的masochists认为每个人的需求和愿望都像他们自己的需要。苦难喜欢公司。 :)

假设您正在为“Web 2.0”世界构建应用程序,或者这对* NIX&amp; amp;同样有用/有益。 MacOS用户:

  • 坚持使用尽可能多的跨平台环境的语言和编译器。
  • Visual Studio中的纯.NET明显优于Win32,但是针对MONO库(可能使用Sharp Develop IDE)进行开发可能是一种更好的方法。
  • 你也可以花时间学习Java,这些技能很好地转移到C#编程(理论上,Java代码理论上可以在任何具有匹配JRE的平台上运行)。我听说它更像是“一次编写,到处调试”,但这可能和C#一样真实(甚至更多)。

答案 5 :(得分:9)

打个比方:如果你以生产汽车(编程)为主,那么了解引擎如何工作(Win32)是非常恰当的。

答案 6 :(得分:8)

简单回答,是的。

答案 7 :(得分:7)

这是任何类似问题的答案。“即使在更高级别的语言/ api Y存在时,学习低级语言/ api X是​​否有意义”

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

您的浏览器有效,因为有人在C中编写了一个OS内核,可以满足您浏览器的所有请求。

它一直到脚本语言。

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

任何抽象级别的api /语言都不是无关紧要的,除非有更好的人在同一级别竞争

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

了解你的行走总是有帮助的。

答案 8 :(得分:7)

是的,原因如下:

1).net包装Win32代码。 .net通常是一个优秀的代码编写系统,但对底层Win32层有一定的了解(现在也有64位代码的oops,WinAPI)可以增强你对真实情况的了解。

2)在这个经济体中,当你找工作时,最好比其他人有一些优势。一些WinAPI经验可能会为您提供此功能。

3)尚未通过.net框架提供某些系统方面,如果要访问这些功能,则需要使用p / invoke(请参阅http://www.pinvoke.net以获得一些帮助)。拥有至少一小部分WinAPI经验将使您的p / invoke开发工作更加高效。

4)(已添加)现在Win8已经存在了一段时间,它仍然是仍然构建在WinAPI之上。 iOS,Android,OS / X和Linux都在那里,但WinAPI仍将存在很多年。

答案 9 :(得分:4)

学习新的编程语言或技术有以下三个原因之一:
1.需要:您正在开始构建Web应用程序的项目,而您对ASP.NET没有任何了解 2.热情:你对ASP.NET MVC非常兴奋。为什么不试试呢? 3.空闲时间:但无论如何谁都有。

了解新事物的最佳理由是极品。如果您需要执行.NET框架无法执行的操作(例如性能),那么WinAPI就是您的解决方案。在此之前,我们一直忙着学习.NET

答案 10 :(得分:4)

对于桌面上的大多数需求,您不需要知道Win32,但是有很多Win32不在.NET中,但它的结果可能不到您应用程序的1%。< / p>

USB支持,HID支持,Windows Media Foundation就在我的头顶。 Win32中有许多很酷的Vista API。

如果你进行桌面编程,学习如何使用Win32 API进行互操作,你会给自己一个大大的帮助,因为当你需要调用Win32时,你将不会花费数周的时间。

答案 11 :(得分:4)

就我个人而言,我并不喜欢Win32 API,但是学习它是有价值的,因为使用GUI比使用Visual Basic这样的语言可以提供更多的控制和效率,而且我相信如果你打算做一个即使你不直接使用它,你应该知道API。这是出于类似于学习C的原因的原因,比如strcpy如何比复制整数花费更多时间,或者为什么应该使用指针将数组作为函数参数而不是按值使用数组。

答案 12 :(得分:3)

学习C或低级语言绝对有用。但是,我没有看到使用非托管WinAPI的任何明显优势。

答案 13 :(得分:3)

是肯定的。看看uTorrent,一个惊人的软件效率。其中一半的小尺寸是因为它的大部分核心组件被重写为不使用gargatuian库。

如果不理解这些库如何与低级API的接口

,那么大部分都无法完成

答案 14 :(得分:3)

我见过低级Windows API代码......它不漂亮......我希望我能忘掉它。我认为在C语言中学习低级别有好处,因为您可以更好地了解硬件架构以及所有这些内容的工作原理。学习旧的Windows API ...我认为这些东西可以留给微软的人,他们可能需要学习它来构建更高级的语言和API ......他们构建它,让它们忍受它; - )

然而,如果您碰巧发现某种情况,您觉得自己无法用更高级别的语言(少数和远程)做您需要做的事情,那么可能会开始危险的潜入这个世界。

答案 15 :(得分:2)

我会这样说的。我不喜欢编程到Win32 API。与托管代码相比,这可能是一种痛苦。但是,我很高兴我知道它,因为我可以编写程序,否则我将无法。我可以编写其他人无法编写的程序。此外,它还可让您更深入地了解托管代码在幕后执行的操作。

答案 16 :(得分:2)

您从学习Win32 API中获得的价值,(除了从了解机器的螺母和螺栓如何组合在一起的各种一般见解之外)取决于您想要实现的目标。很多Win32 API已经很好地包装在.NET库类中,但不是全部。例如,如果您正在寻找一些严肃的音频编程,那么Win32 API的这一部分将是一个很好的学习主题,因为只有最基本的操作可以从.NET类中获得。最后我检查了托管的DirectX DirectSound库很糟糕。


冒着无耻的自我推销的风险......

我刚刚遇到过Win32 API是我唯一的选择。我想在列表框中的每个项目上有不同的工具提示。我写了我在this question上的表现。

答案 17 :(得分:2)

这与问题真的相同,我应该学习像C(甚至是汇编程序)这样的低级语言。

其中的编码肯定较慢(虽然结果当然要快得多),但它的真正优势在于您可以深入了解接近系统级别的情况,而不仅仅是了解其他人的隐喻。正在继续。

当事情不能很好地运行,或者速度不够快或者你需要的那种粒度时,它也会更好。 (至少做一些子类化和超类化。)

答案 18 :(得分:2)

即使是非常高级的语言,您仍然可以使用API​​。为什么?并非API的每个方面都被各种库,框架等复制。只要您需要API来完成您要执行的操作,您就需要学习API。 (而且不再。)

答案 19 :(得分:2)

了解Windows API的可用内容非常重要。我不认为你需要用它来编写代码,但你应该知道它是如何工作的。 .NET Framework包含许多功能,但它不提供整个Windows API的托管代码等效项。有时你必须更接近金属,知道那里的东西以及它的行为将使你更好地理解如何使用它。

答案 20 :(得分:2)

除了一些非常特殊的情况,当你需要直接访问API时,我会说不。

学习正确实现本机API调用需要花费大量的时间和精力,并且返回的值不值得。我宁愿花时间学习一些新的热门技术或框架,让你的生活更轻松,编程也更少痛苦。不是几十年前过时的COM库,没有人真正使用它(对COM用户来说很抱歉)。

请不要因为这个观点而嘲笑我。我知道这里的很多工程师都有很好奇的灵魂,学习如何运作并没有错。好奇是好的,真的有助于理解。但从管理的角度来看,我宁愿花一周时间学习如何开发Android应用,而不是如何调用OLE或COM。

答案 21 :(得分:1)

如果您计划开发跨平台应用程序,如果您使用win32,那么您的应用程序可以通过WINE轻松在Linux上运行。这导致高度可维护的应用程序。这是学习win32的优点之一。