Windows API 集

重要

本主题中的信息适用于 Windows 10 及更高版本的所有版本。 我们将此处的这些版本称为“Windows”,并在必要时调用任何例外。

所有版本的 Windows 共享操作系统 (操作系统) 组件的公共基础,这些组件称为核心 OS (在某些情况下,此通用基础也称为OneCore) 。 在核心 OS 组件中,Win32 API 组织成称为 API 集的功能组。

API 集的目的是提供与实现给定 Win32 API 的主机 DLL 以及 API 所属的功能协定的体系结构分离。 API 集在实现和协定之间提供的分离为开发人员提供了许多工程优势。 具体而言,在代码中使用 API 集可以提高与 Windows 设备的兼容性。

API 集专门解决以下情况:

  • 尽管电脑支持 Win32 API 的全部范围,但只有一部分 Win32 API 在其他 Windows 设备(如 HoloLens、Xbox 和其他设备)上可用。 API 集名称提供了一种查询机制,用于彻底检测 API 在任何给定设备上是否可用。

  • 某些 Win32 API 实现存在于跨不同 Windows 设备的具有不同名称的 DLL 中。 检测 API 可用性和延迟加载 API 时,使用 API 集名称而不是 DLL 名称,为实现提供正确的路由,无论 API 在何处实际实现。

有关详细信息,请参阅 API 集加载程序操作检测 API 集可用性

API 集和 dll 是否相同?

否 - API 集名称是物理.dll文件的虚拟别名。 这是一种隐藏实现的技术,调用方无需确切地知道哪个模块承载了信息。

该技术允许重构模块 (拆分、合并、重命名等,) 不同的 Windows 版本和版本。 应用仍会链接,并且仍会在运行时路由到正确的代码。

那么,为什么 API 集的名称中包含 .dll ? 原因是实现 DLL 加载程序 的方式。 加载程序是 OS 的一部分,用于加载 DLL 和/或解析对 DLL 的引用。 在前端,加载程序要求传递给 LoadLibrary 的任何字符串都以“.dll”结尾。 但在该前端之后,加载程序可以去除该后缀,并使用生成的字符串查询 API 集数据库。

LoadLibrary (和延迟加载) 成功,API 集名称 () 中带有“.dll”;但电脑上的任何地方都不一定有具有该名称的实际文件。

链接伞式库

为了更轻松地将代码限制为核心 OS 支持的 Win32 API,我们提供了一系列 伞式库。 例如,名为 的 OneCore.lib 伞式库为所有 Windows 设备通用的 Win32 API 子集提供导出。

有关更多详细信息,请参阅 Windows umbrella 库

API 集协定名称

API 集由强协定名称标识,该名称遵循库加载程序识别的这些标准约定。

  • 名称必须以字符串 api-ext- 开头。
    • api 开头 的名称表示保证存在于所有 Windows 版本中的 API。
    • ext- 开头的名称表示可能并非在所有 Windows 版本中存在的 API。
  • 名称必须以序列 l<n-n-n<<>>> 结尾,其中 n 由十进制数字组成。
  • 名称的正文可以是字母数字字符,也可以是短 - 划线 () 。
  • 此名称不区分大小写。

下面是 API 集协定名称的一些示例:

  • api-ms-win-core-ums-l1-1-0
  • ext-ms-win-com-ole32-l1-1-5
  • ext-ms-win-ntuser-window-l1-1-0
  • ext-ms-win-ntuser-window-l1-1-1

可以在加载程序操作(如 LoadLibraryP/Invoke) 的上下文中使用 API 集名称,而不是 DLL 模块名称,以确保在当前设备上实际实现 API 的位置正确路由。 但是,执行此操作时,必须将字符串 .dll 追加到协定名称的末尾。 这是加载程序正常运行的要求,实际上并不被视为协定名称的一部分。 尽管协定名称在此上下文中看起来类似于 DLL 名称,但它们与 DLL 模块名称基本不同,并且不直接引用磁盘上的文件。

除了在加载程序操作中追加字符串 .dll 外,API 集协定名称应被视为与特定协定版本相对应的不可变标识符。

标识 Win32 API 的 API 集

若要确定特定 Win32 API 是否属于 API 集,请查看 API 参考文档中的要求表。 如果 API 属于 API 集,则本文中的要求表列出了 API 集名称和首次将 API 引入 API 集的 Windows 版本。 有关属于 API 集的 API 示例,请参阅以下文章:

在本节中