【问题标题】:How does Windows API work?Windows API 是如何工作的?
【发布时间】:2015-06-01 12:27:01
【问题描述】:

似乎我们可以通过包含所需的头文件来免费使用 Windows API。但是,鉴于头文件没有函数定义而是声明,我无法让自己理解这是怎么可能的,这应该被认为是一个错误,因为它缺少实现细节。编译器如何定位实现细节并将其映射到内存中?

【问题讨论】:

  • Windows 内置了所有功能,并为其提供了 API。包含连接到该功能的库。标头只是为这些函数提供定义。该实现由 Windows 通过 DLL 提供。找到解释这些基础知识的教程或书籍可能是个好主意。
  • @KenWhite 您的意思是说 DLL 会被自动考虑在内,以便在链接过程中,编译器得到它所需要的一切?为了使它有意义,头文件必须确保编译器知道需要什么 DLL。它是怎么做的?
  • 不,我的意思是头文件提供了声明,而导入库的包含提供了与内置 DLL 功能的链接。同样,寻找教程可能是个好主意。使用 DLL 和导入库是使用 Windows API 的基本信息,它在很多地方都可用。

标签: c winapi


【解决方案1】:

Windows API 在您安装 Windows 时安装的 DLL 中实现。这些 DLL 位于 System 目录中,具有 User32.dll、Kernel32.dll 等名称。

正如您正确指出的,编译器随附的 Windows API 头文件仅包含声明。当您的 C 程序调用其中一个函数(或任何其他在头文件中标识但未与您的项目实际编译的函数)时,编译器会在生成的目标文件中放置一条记录,实际上是“我需要调用一个名为 GetWindowRect 的函数(或任何你调用的函数的名称)。"

链接器是真正解析名字的东西。如果您查看链接器选项,您会发现它正在链接一些库,如 User32.lib、Kernel32.lib 等。这些库包含的编译函数只不过是存根——导致加载相应 DLL 的代码,然后调用DLL中的函数。

它比这更复杂一些,但这是一般的想法。总结:

  1. 您包含 Windows API 头文件。
  2. 您的代码调用了在这些头文件中声明的一个或多个 Windows API 函数。
  3. 编译器会记下链接器以解析这些 API 函数调用。
  4. 链接器通过在链接器命令行上指定的库中查找存根函数来解析调用。
  5. 在运行时,调用其中一个函数会导致加载相应的 DLL,然后将控制权转移到 DLL 中的函数。

【讨论】:

  • 我对您的回答还有一个问题。您说 .lib 中的编译代码会导致加载 DLL。但是,我不知道为什么需要 DLL。理论上,我认为这些库足以提供实现细节,不是吗?是否有任何理由将二进制代码包装两次?
  • @user3647351:Windows API 函数的实现细节包含在 DLL 中。 .lib 文件中的函数在您的编译代码和位于 DLL 中的编译代码之间提供了桥梁。
  • 使用了 DLL,因此实现可以重复用于多个进程,并且更新只能安装一次。 @导入的 .lib 文件中没有函数。它们包含对实际 DLL 函数的引用。链接器将这些引用放入最终可执行文件的 IMPORTS 表中。当可执行文件在运行时加载到内存中时,OS Loader 使用实际 DLL 函数的地址修补 IMPORTS 表。当您的代码调用静态链接的 Win32 API 函数时,它会直接跳转到 DLL 函数中。
  • 注意有两种.lib文件;这种桥接您的应用程序和 DLL,以及包含实际代码的静态库。许多库(包括 C 运行时库)都带有这两种类型,您可以选择使用哪一种。 Windows API 不提供静态库,因为使用静态库意味着您不仅需要为每个新版本的 Windows 重新构建应用程序,而且每次 Microsoft 发布 Windows 更新时都需要重新构建应用程序。
【解决方案2】:

它的工作方式与任何其他库相同,例如 C stdlib - 您的程序只需要“知道”函数的原型(以及底层符号名称)。编译后进行链接 - 即丢失的符号(函数定义)与正确的库“链接”。

【讨论】:

  • 但是,当使用 Windows API 时,我们从未显式编译在头文件中备份函数声明所需的源文件。我的意思是,即使我们没有所需的适当源文件,链接怎么会发挥作用?
  • 取决于您使用的链接器,如果您不需要添加任何特殊参数并且“它可以正常工作”,那么链接器会自动为您链接到某些 .lib 文件。
猜你喜欢
  • 2014-06-19
  • 1970-01-01
  • 2011-02-16
  • 1970-01-01
  • 1970-01-01
  • 2018-04-12
  • 2012-06-01
  • 2018-07-01
  • 2021-01-01
相关资源
最近更新 更多