55

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

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

4

22 回答 22

65

这个问题与宗教有关:)但无论如何我都会给出我的想法。

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

另外,如果您了解框架使用的底层 API 的性质,那么您将更好地选择在给定场景中应该使用的库功能。

干杯!

于 2008-08-08T01:00:49.203 回答
23

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

一方面,Win32 API 非常酷。它就像 C 标准 API 的扩展(fopen当你有CreateFile. ,他们有“一切都是……窗口”(不开玩笑!看CreateWindow!)。

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

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

最后一手(三手???),考虑一些使用遗留 API 的人自己使用遗留代码样式。当您听到“const傻瓜”或“我不使用名称空间,因为它们会降低运行时速度”或更好的“嘿,谁需要 C++?我用我自己品牌的面向对象 C 编码!!! ”(不开玩笑……在专业的环境中,结果是相当的景象……),你会在断头台前感受到那种只有被谴责的恐惧感。

所以……总而言之,这是一次有趣的经历。

编辑

重读这篇文章后,我发现它可能被视为过于消极。它不是。

了解事物在幕后的运作方式有时很有趣(也很令人沮丧)。你会明白,尽管有巨大的(不可能的?)限制,Win32 API 团队做了出色的工作,以确保一切,从你的“旧 Win16 程序”到你的“最后一个 Win64 over-the-top 应用程序”,可以一起工作,过去、现在和未来。

问题是:你真的想要吗?

因为花费数周时间来做可以在其他更高级和/或面向对象的 API 中完成(并且做得更好)的事情可能会非常消极(现实生活中的经验:Win API 需要 3 周,而 3 周需要 4 小时其他语言和/或库)。

无论如何,您会发现 Raymond Chen 的博客非常有趣,因为他的内部人士对 Win API 及其多年来的演变的看法:

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

于 2008-09-19T18:37:48.753 回答
16

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

于 2008-08-08T00:31:04.660 回答
16

本机 API 是“真正的”操作系统 API。.NET 库(除了少数例外)只不过是围绕它们的精美包装器。所以,是的,我想说任何能够理解 .NET 及其所有复杂性的人,都可以理解相对平凡的事情,比如在没有中间人帮助的情况下与 API 交谈。

只需尝试从托管代码进行 DLL 注入。这是不可能的。您将被迫为此编写本机代码,用于窗口调整、真正的子类化以及其他许多事情。

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

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

于 2008-08-08T00:53:24.663 回答
11

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

  • 了解较低级别的系统肯定会提供有用的信息——它们是如何工作的,你的代码如何与它们交互(即使只是间接的),以及在哪些地方你有更高级别抽象中不可用的附加选项
  • 有时您的代码可能不够高效、高性能或精确,无法满足您的要求
  • 然而,在越来越多的情况下,像我们这样的人(从未学习过“非托管编码”)将能够在不“学习”Win32 的情况下完成我们尝试做的编程。
  • 此外,有很多网站提供工作示例、代码片段甚至功能齐全的源代码,您可以“利用”(借用、抄袭 - 但请检查您是否遵守任何重用许可或版权!)来填写在 .NET 框架类库(或您可以下载或许可的库)未处理的任何间隙中。
  • 如果你能在不乱用 Win32 的情况下完成你需要的壮举,并且你在开发格式良好、可读的托管代码方面做得很好,那么我会说掌握 .NET 将是一个比分散自己瘦身更好的选择在两个非常不同的环境中。
  • 如果您经常需要利用那些尚未获得良好框架类库覆盖的 Windows 功能,那么请务必学习您需要的技能。
  • 我个人花了太多时间担心编码的“其他领域”,我应该理解这些领域以产生“好程序”,但是那里有很多自虐狂认为每个人的需求和愿望都像他们自己的一样。苦难爱陪伴。:)

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

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

类比:如果您以制造汽车为生(编程),那么了解引擎的工作原理(Win32)非常相关。

于 2008-08-08T01:01:44.457 回答
8

简单的回答,是的。

于 2008-08-08T01:16:26.580 回答
8

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

是的

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

您的浏览器可以正常工作,因为有人用 C 语言编写了一个操作系统内核来满足您浏览器的所有请求。

它一直到脚本语言。

无论大小,总有一个市场和机会可以在任何抽象级别上编写一些东西。你只需要喜欢它并适合合适的工作。

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

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

知道你在走什么总是有帮助的。

于 2010-05-29T03:17:49.137 回答
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 仍将存在很多年。

于 2009-07-17T06:17:04.070 回答
4

学习一门新的编程语言或技术是出于以下三个原因之一:
1. 需要:您正在开始一个构建 Web 应用程序的项目,但您对 ASP.NET 一无所知
2. 热情:您对ASP.NET MVC。为什么不试试呢?
3. 空闲时间:但无论如何谁有。

学习新事物的最佳理由是需要。如果您需要做一些 .NET 框架不能做的事情(例如性能),那么 WinAPI 就是您的解决方案。在那之前,我们一直忙于学习 .NET

于 2008-08-08T01:56:33.723 回答
4

对于桌面上的大多数需求,您不需要了解 Win32,但是有很多 Win32 不在 .NET 中,但它存在于最终可能不到您应用程序的 1% 的支出中。

USB 支持、HID 支持、Windows Media Foundation 就在我的脑海中。有许多很酷的 Vista API 只能从 Win32 获得。

如果您进行桌面编程,学习如何与 Win32 API 进行互操作将对您大有裨益,因为当您确实需要调用 Win32 时,您不会花费数周时间摸索。

于 2008-08-08T16:53:50.550 回答
4

就我个人而言,我不太喜欢 Win32 API,但学习它是有价值的,因为与 Visual Basic 之类的语言相比,使用 GUI 的 API 将允许更多的控制和效率,我相信如果你打算谋生写作软件即使您不直接使用 API,您也应该知道它。这是出于类似于学习 C 的好处的原因,例如 strcpy 如何比复制整数花费更多时间,或者为什么应该使用指向数组的指针作为函数参数而不是按值排列的数组。

于 2008-08-21T13:07:30.423 回答
3

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

于 2008-08-08T00:35:21.720 回答
3

我见过低级别的 Windows API 代码……它不漂亮……我希望我能忘记它。我认为像 C 一样学习低级是有好处的,因为你可以更好地理解硬件架构以及所有这些东西是如何工作的。学习旧的 Windows API……我认为这些东西可以留给微软的人,他们可能需要学习它来构建更高级别的语言和 API……他们构建了它,让他们受苦 ;-)

然而,如果你碰巧发现一种情况,你觉得你无法用更高级别的语言做你需要做的事情(很少而且很远),那么也许开始危险地潜入那个世界。

于 2008-08-08T00:40:05.453 回答
3

是的。看看 uTorrent,一个惊人的软件效率。它的小尺寸有一半是由于它的大部分核心组件都被重写为不使用 gargatuian 库。

如果不了解这些库如何与较低级别的 API 接口,大部分工作都无法完成

于 2009-06-11T03:53:11.667 回答
2

了解 Windows API 的可用功能很重要。我认为你不需要用它编写代码,但你应该知道它是如何工作的。.NET Framework 包含许多功能,但它不为整个 Windows API 提供托管代码等效项。有时你必须离金属更近一点,知道下面有什么以及它的行为方式会让你更好地了解如何使用它。

于 2008-08-08T02:21:47.853 回答
2

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

在其中进行编码肯定会更慢(尽管结果当然要快得多),但它的真正优势是您可以深入了解接近系统级别发生的事情,而不仅仅是了解其他人对正在发生的事情的隐喻.

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

于 2008-09-12T06:20:26.567 回答
2

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

于 2008-09-26T02:01:45.877 回答
2

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


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

我刚刚遇到了 Win32 API 是我唯一选择的情况。我想在列表框中的每个项目上都有不同的工具提示。我在这个问题上写了我是如何做到的。

于 2008-09-26T03:01:20.087 回答
2

即使在非常高级的语言中,您仍然可以使用 API。为什么?并不是 API 的每个方面都被各种库、框架等复制了。只要您需要 API 来完成您正在尝试做的事情,您就需要学习 API。(不再是。)

于 2009-06-28T18:49:44.737 回答
2

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

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

请不要因为这个观点而向我扔石头。我知道这里的很多工程师都非常好奇,学习事物的工作原理并没有错。好奇心是好的,真的有助于理解。但从管理的角度来看,我宁愿花一周时间学习如何开发 Android 应用程序,而不是如何调用 OLE 或 COM。

于 2012-04-23T16:39:30.740 回答
1

如果你打算开发一个跨平台的应用程序,如果你使用win32,那么你的应用程序可以很容易地通过WINE在linux上运行。这导致了一个高度可维护的应用程序。这是学习win32的好处之一。

于 2009-06-28T18:59:47.883 回答