windows 学习低级 WinAPI 编程还有意义吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5507/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does it still make sense to learn low level WinAPI programming?
提问by Camilo Díaz Repka
Does it make sense, having all of the C#-managed-bliss, to go back to Petzold's Programming Windows and try to produce code w/ pure WinAPI?
拥有所有 C# 管理的幸福,回到 Petzold 的 Windows 编程并尝试使用纯 WinAPI 生成代码是否有意义?
What can be learn from it? Isn't it just too outdated to be useful?
从中可以学到什么?是不是太过时了而没有用?
回答by OJ.
This question is bordering on religious :) But I'll give my thoughts anyway.
这个问题接近于宗教 :) 但无论如何我都会给出我的想法。
I do see value in learing the Win32 API. Most, if not all, GUI libraries (managed or unmanaged) result in calls to the Win32 API. Even the most thorough libraries don't cover 100% of the API, and hence there are always gaps which need to be plugged by direct API calls or P/invoking. Some of the names of the wrappers around the API calls have similar names to the underlying API calls, but those names aren't exactly self-documenting. So understanding the underlying API, and the terminology used therein, will aid in understanding the wrapper APIs and what they actually do.
我确实看到了学习 Win32 API 的价值。大多数(如果不是全部)GUI 库(托管或非托管)都会导致调用 Win32 API。即使是最全面的库也不能覆盖 100% 的 API,因此总是存在需要通过直接 API 调用或 P/invoking 来填补的空白。API 调用周围的一些包装器的名称与底层 API 调用具有相似的名称,但这些名称并不完全是自记录的。因此,了解底层 API 以及其中使用的术语将有助于理解包装 API 及其实际用途。
Plus, if you understand the nature of the underlying APIs that are used by frameworks, then you will make better choices with regards to which library functionality you should use in a given scenario.
另外,如果您了解框架使用的底层 API 的性质,那么您将在给定场景中应该使用哪些库功能方面做出更好的选择。
Cheers!
干杯!
回答by paercebal
I kept to standard C/C++ for years before learning Win32 API, and to be quite blunt, the "learning Win32 API" part is not the best technical experience of my life.
在学习 Win32 API 之前,我多年来一直遵循标准的 C/C++,坦率地说,“学习 Win32 API”部分并不是我一生中最好的技术体验。
In one hand Win32 API is quite cool. It's like an extension of the C standard API (who needs fopen
when you can have CreateFile
. But I guess UNIX/Linux/WhateverOS have the same gizmo functions. Anyway, in Unix/Linux, they have the "Everything is a file". In Windows, they have the "Everything is a... Window" (no kidding! See CreateWindow
!).
一方面,Win32 API 非常酷。这就像 C 标准 API 的扩展(fopen
当你可以拥有时谁需要CreateFile
。但我猜 UNIX/Linux/WhateverOS 具有相同的小工具功能。无论如何,在 Unix/Linux 中,它们具有“一切都是文件”。在 Windows 中,他们有“一切都是一个......窗口”(不开玩笑!看CreateWindow
!)。
In the other hand, this is a legacy API. You will be dealing with raw C, and raw C madness.
另一方面,这是一个遗留 API。您将处理原始 C 和原始 C 疯狂。
- Like telling one's structure its own size to pass through a
void *
pointer to some Win32 function. - Messaging can be quite confusing, too: Mixing C++ objects with Win32 windows lead to very interesting examples of Chicken or Eggproblem (funny moments when you write a kind of
delete this ;
in a class method). - Having to subclass a WinProc when you're more familiar with object inheritance is head-splitting and less than optimal.
- And of course, there is the joy of "Why in this fracking world they did this thing this way ??" moments when you strike your keyboard with your head once too many and get back home with keys engraved in your forehead, just because someone thought it more logical to write an API to enable the changing of the color of a "Window", not by changing one of its properties, but by asking it to its parent window.
- etc.
- 就像通过一个
void *
指向某个 Win32 函数的指针告诉一个结构它自己的大小一样。 - 消息传递也可能非常令人困惑:将 C++ 对象与 Win32 窗口混合会导致非常有趣的鸡或蛋问题示例(当您
delete this ;
在类中编写一种方法时的有趣时刻)。 - 当您更熟悉对象继承时,必须对 WinProc 进行子类化是令人头疼的,而且不是最佳选择。
- 当然,还有“为什么在这个水力压裂的世界里他们会这样做?”的喜悦,当你用头敲击键盘太多次,然后带着刻在你额头上的钥匙回家,只是因为有人认为编写一个 API 来更改“窗口”的颜色更合乎逻辑,不是通过更改其属性之一,而是通过向其父窗口询问。
- 等等。
In the last hand (three hands ???), consider that some people working with legacy APIs are themselves using legacy code styling. The moment you hear "const
is for dummies" or "I don't use namespaces because they decrease the runtime speed", or the even better "Hey, who needs C++? I code in my own brand of object-oriented C!!!" (No kidding... In a professional environment, and the result was quite a sight...), you'll feel the kind of dread only condemned feel in front of the guillotine.
最后一手(三只手???),考虑到一些使用遗留 API 的人自己也在使用遗留代码样式。当您听到“const
适用于傻瓜”或“我不使用命名空间,因为它们会降低运行速度”,或者甚至更好的“嘿,谁需要 C++?我用自己的面向对象 C 语言编码!!!”(不开玩笑……在专业的环境中,结果是相当壮观的……),你会在断头台前感受到那种只有谴责的恐惧感。
So... All in all, it's an interestingexperience.
所以......总而言之,这是一次有趣的经历。
Edit
编辑
After re-reading this post, I see it could be seen as overly negative. It is not.
重新阅读这篇文章后,我认为它可能被视为过于消极。它不是。
It is sometimes interesting (as well as frustrating) to know how the things work under the hood. You'll understand that, despite enormous (impossible?) constraints, the Win32 API team did wonderful work to be sure everything, from you "olde Win16 program" to your "last Win64 over-the-top application", can work together, in the past, now, and in the future.
有时了解这些事物的内部运作方式很有趣(也很令人沮丧)。您会明白,尽管存在巨大(不可能?)限制,但 Win32 API 团队做了出色的工作,以确保从“旧 Win16 程序”到“最后一个 Win64 over-the-top 应用程序”,都可以协同工作,在过去、现在和未来。
The question is: Do you really want to?
问题是:你真的想要吗?
Because spending weeks to do things that could be done (and done better) in other more high-level and/or object-oriented API can be quite de-motivational (real life experience: 3 weeks for Win API, against 4 hours in three other languages and/or libraries).
因为花费数周时间去做可以在其他更高级和/或面向对象的 API 中完成(并且做得更好)的事情可能会非常缺乏动力(现实生活经验:Win API 为 3 周,而在三个其他语言和/或库)。
Anyway, you'll find Raymond Chen's Blog very interesting because of his insider's view on both Win API and its evolution through the years:
无论如何,你会发现 Raymond Chen 的博客非常有趣,因为他的内部人士对 Win API 及其多年来的演变的看法:
回答by paercebal
The native APIs are the "real" operating system APIs. The .NET library is (with few exceptions) nothing more than a fancy wrapper around them. So yes, I'd say that anybody who can understand .NET with all its complexity, can understand relatively mundane things like talking to the API without the benefit of a middle-man.
本机 API 是“真正的”操作系统 API。.NET 库(除了少数例外)只不过是围绕它们的精美包装器。所以是的,我想说任何能够理解 .NET 及其复杂性的人,都可以理解相对平凡的事情,比如在没有中间人的情况下与 API 交谈。
Just try to do DLL Injection from managed code. It can't be done. You will be forced to write native code for this, for windowing tweaks, for real subclassing, and a dozen other things.
只需尝试从托管代码中进行 DLL 注入即可。做不到。您将被迫为此编写本机代码,以进行窗口调整、真正的子类化以及其他许多事情。
So yes: you should (must) know both.
所以是的:你应该(必须)两者都知道。
Edit: even if you plan to use P/Invoke.
编辑:即使您打算使用 P/Invoke。
回答by Ed.
Absolutely. When nobody knows the low level, who will update and write the high level languages? Also, when you understand the low level stuff, you can write more efficient code in a higher level language, and also debug more efficiently.
绝对地。当没有人知道低级时,谁来更新和编写高级语言?此外,当您了解底层的东西时,您可以用更高级的语言编写更高效的代码,也可以更高效地调试。
回答by ParanoidMike
On the assumption that you're building apps targeted at Windows:
假设您正在构建针对 Windows 的应用程序:
- it can sure be informative to understand lower levels of the system - how they work, how your code interacts with them (even if only indirectly), and where you have additional options that aren't available in the higher-level abstractions
- there are times when your code might not be as efficient, high-performance or precise enough for your requirements
- However, in more and more cases, folks like us (who never learned "unmanaged coding") will be able to pull off the programming we're trying to do without "learning" Win32.
- Further, there's plenty of sites that provide working samples, code fragments and even fully-functional source code that you can "leverage" (borrow, plagiarize - but check that you're complying with any re-use license or copyright!) to fill in any gaps that aren't handled by the .NET framework class libraries (or the libraries that you can download or license).
- If you can pull off the feats you need without messing around in Win32, and you're doing a good job of developing well-formed, readable managed code, then I'd say mastering .NET would be a better choice than spreading yourself thin over two very different environments.
- If you frequently need to leverage those features of Windows that haven't received good Framework class library coverage, then by all means, learn the skills you need.
- I've personally spent far too much time worrying about the "other areas" of coding that I'm supposedto understand to produce "good programs", but there's plenty of masochists out there that think everyone's needs and desires are like their own. Misery loves company. :)
- 了解系统的较低级别肯定会提供信息 - 它们如何工作,您的代码如何与它们交互(即使只是间接的),以及您在哪些地方有更高级别抽象中不可用的其他选项
- 有时您的代码可能不够高效、高性能或不够精确以满足您的要求
- 然而,在越来越多的情况下,像我们这样的人(从未学习过“非托管编码”)将能够在不“学习”Win32 的情况下完成我们正在尝试进行的编程。
- 此外,有很多站点提供了工作示例、代码片段甚至全功能源代码,您可以“利用”(借用、抄袭——但请检查您是否遵守任何重用许可或版权!)来填写在 .NET 框架类库(或您可以下载或许可的库)未处理的任何差距中。
- 如果你可以在不乱用 Win32 的情况下完成你需要的壮举,并且你在开发格式良好、可读的托管代码方面做得很好,那么我会说掌握 .NET 将是一个更好的选择,而不是分散自己的注意力在两个截然不同的环境中。
- 如果您经常需要利用那些尚未获得良好框架类库覆盖率的 Windows 功能,那么一定要学习您需要的技能。
- 我个人花了太多时间担心编码的“其他领域”,我应该理解这些领域才能产生“好的程序”,但是有很多受虐狂认为每个人的需求和愿望都像他们自己的一样。苦难爱陪伴。:)
On the assumption that you're building apps for the "Web 2.0" world, or that would be just as useful/beneficial to *NIX & MacOS users:
假设您正在为“Web 2.0”世界构建应用程序,或者对 *NIX 和 MacOS 用户同样有用/有益:
- Stick with languages and compilers that target as many cross-platform environments as possible.
- pure .NET in Visual Studio is better than Win32 obviously, but developing against the MONO libraries, perhaps using the Sharp Develop IDE, is probably an even better approach.
- you could also spend your time learning Java, and those skills would transfer very well to C# programming (plus the Java code would theoretically run on any platform with the matching JRE). I've heard it said that Java is more like "write once, debug everywhere", but that's probably as true as (or even moreso than) C#.
- 坚持使用针对尽可能多的跨平台环境的语言和编译器。
- Visual Studio 中的纯 .NET 显然比 Win32 好,但是针对 MONO 库进行开发,也许使用 Sharp Develop IDE,可能是更好的方法。
- 你也可以花时间学习 Java,这些技能会很好地转移到 C# 编程中(而且 Java 代码理论上可以在任何具有匹配 JRE 的平台上运行)。我听说 Java 更像是“一次编写,到处调试”,但这可能与 C# 一样(甚至比)C# 更真实。
回答by Joel Lucsy
Analogy: If you build cars for a living (programming), then its very pertinent to know how the engine works (Win32).
类比:如果您以制造汽车为生(编程),那么了解引擎的工作原理非常重要(Win32)。
回答by Stephen Cox
Simple answer, YES.
简单的回答,是的。
回答by Jay
Yes, for a few reasons:
是的,有几个原因:
1) .net wraps Win32 code. .net is usually a superior system to code against, but having some knowledge of the underlying Win32 layer (oops, WinAPI now that there is 64-bit code too) bolsters your knowledge of what is really happening.
1) .net 包装 Win32 代码。.net 通常是一个优秀的编码系统,但是对底层 Win32 层(哎呀,WinAPI 现在也有 64 位代码)有一些了解可以增强你对真正发生的事情的了解。
2) in this economy, it is better to have some advantages over the other guy when you are looking for a job. Some WinAPI experience may provide this for you.
2)在这个经济环境下,找工作的时候最好比其他人有一些优势。一些 WinAPI 经验可能会为您提供这些。
3) some system aspects are not available through the .net framework yet, and if you want to access those features you will need to use p/invoke (see http://www.pinvoke.netfor some help there). Having at least a smattering of WinAPI experience will make your p/invoke development effort a lot more efficient.
3) 某些系统方面还不能通过 .net 框架使用,如果您想访问这些功能,您将需要使用 p/invoke(请参阅http://www.pinvoke.net以获得一些帮助)。至少有一点 WinAPI 经验将使您的 p/invoke 开发工作更有效率。
4) (added) Now that Win8 has been around for awhile, it is stillbuilt on top of the WinAPI. iOS, Android, OS/X, and Linux are all out there, but the WinAPI will still be out there for many many years.
4)(补充)现在Win8已经出现了一段时间,它仍然建立在WinAPI之上。iOS、Android、OS/X 和 Linux 都在那里,但 WinAPI 仍然会存在很多年。
回答by Senthil
This is the answer to any question that is like.. "does it make sense to learn a low level language/api X even when a higher level language/api Y is there"
这是对任何类似问题的答案.. “即使存在高级语言/api Y,学习低级语言/api X 是否有意义”
YES
是的
You are able to boot up your Windows PC (or any other OS) and ask this question in SO because a couple of guys in Microsoft wrote 16-bit assembly code that loads your OS.
您可以启动您的 Windows PC(或任何其他操作系统)并在 SO 中提出这个问题,因为 Microsoft 的几个人编写了加载您的操作系统的 16 位汇编代码。
Your browser works because someone wrote an OS kernel in C that serves all your browser's requests.
您的浏览器之所以能正常工作,是因为有人用 C 编写了一个操作系统内核,可以为您浏览器的所有请求提供服务。
It goes all the way up to scripting languages.
它一直到脚本语言。
Big or small, there is always a market and opportunity to write something in any level of abstraction. You just have to like it and fit in the right job.
无论大小,总有一个市场和机会来编写任何抽象级别的东西。你只需要喜欢它并适合合适的工作。
No api/language at any level of abstraction is irrelevent unless there is a better one competing at the same level.
任何抽象级别的 api/语言都不是无关紧要的,除非在同一级别有更好的竞争。
Another way of looking at it: A good example from one of Michael Abrash's book: A C programmer was given the task of writing a function to clear the screen. Since C was a better (higher level) abstraction over assembly and all, the programmer only knew C and knew it well. He did his best - he moved the cursor to each location on the screen and cleared the character there. He optimized the loop and made sure it ran as fast as it could. But still it was slow... until some guy came in and said there was some BIOS/VGA instruction or something that could clear the screen instantly.
另一种看待它的方式:Michael Abrash 书中的一个很好的例子:AC 程序员的任务是编写一个函数来清除屏幕。由于 C 是比汇编等更好(更高级别)的抽象,因此程序员只了解 C 并且非常了解它。他尽力了——他将光标移动到屏幕上的每个位置并清除那里的角色。他优化了循环并确保它尽可能快地运行。但它仍然很慢......直到有人进来并说有一些BIOS / VGA指令或可以立即清除屏幕的东西。
It always helps to know what you are walking on.
知道你在做什么总是有帮助的。
回答by Amr
Learning a new programming language or technology is for one of three reasons:
1. Need: you're starting a project for building a web application and you don't know anything about ASP.NET
2. Enthusiasm: you're very excited about ASP.NET MVC. why not try that?
3. Free time: but who has that anyway.
学习一门新的编程语言或技术是出于以下三个原因之一:
1. 需要:您正在开始一个构建 Web 应用程序的项目,而您对 ASP.NET 一无所知
2. 热情:您对ASP.NET MVC。为什么不试试呢?
3. 空闲时间:但无论如何谁有空闲时间。
The best reason to learn something new is Need. If you need to do something that the .NET framework can't do (like performance for example) then WinAPI is your solution. Until then we keep ourself busy with learning about .NET
学习新事物的最佳理由是需要。如果您需要做一些 .NET 框架不能做的事情(例如性能),那么 WinAPI 就是您的解决方案。在那之前,我们会一直忙于学习 .NET