API 集操作加载程序

重要

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

API 集依赖于库加载程序中的 OS 支持,以有效地将模块命名空间重定向引入库绑定过程。 库加载程序使用 API 集协定名称执行对目标主机二进制文件的引用的运行时重定向,该二进制文件包含 API 集的相应实现。

当加载程序在运行时遇到 API 集的依赖项时,加载程序会查阅映像中的配置数据,以标识 API 集的主机二进制文件。 此配置数据称为 API 集架构。 架构被组装为 OS 的属性,API 集和二进制文件之间的映射可能会因给定设备中包含的二进制文件而异。 架构使单个二进制文件中的导入函数能够在不同的设备上正确路由,即使二进制主机的模块名称已在不同的 Windows 设备上重命名或完全重构。

Windows 支持使用 API 集并与之交互的两种标准技术:直接转发反向转发

直接转发

在此配置中,使用的代码直接导入 API 集模块名称。 此导入在单个操作中解析,是开销最小、效率最高的方法。 从概念上讲,此解析可能指向不同 Windows 设备上的不同二进制文件,如以下示例所示:

导入的 API 集:api-feature1-l1-1-0.dll

  • Windows 电脑 ->feature1.dll
  • HoloLens ->feature1_holo.dll
  • IoT ->feature1_iot.dll

由于映射保存在自定义架构数据存储库中,这意味着以 .dll 结尾的 API 集名称不会直接引用磁盘上的文件。 API 集名称的 .dll 部分只是加载程序所需的约定。 API 集名称更像是物理 DLL 文件的别名或虚拟名称。 这使得该名称可在所有 Windows 设备上移植。

反向转发

虽然 API 集名称为跨设备的模块提供稳定的命名空间,但将每个二进制文件转换为此新系统并不总是可行。 例如,一个应用程序可能已经被广泛使用了很多年,并且重新编译应用程序的二进制文件可能不可行。 此外,某些应用程序可能需要继续在引入特定 API 集之前生成的系统上运行。

为了适应这种级别的兼容性,在涵盖 Win32 API 图面子集的所有 Windows 设备上都提供了一个转发器系统。 这些转发器使用 Windows 电脑上引入的模块名称,并利用 API 集系统在所有 Windows 设备上提供兼容性。

加载程序操作的行为如下所示:

  1. 在 Windows 电脑以外的设备上,加载程序会显示设备上不存在的旧版 Windows 电脑模块名称依赖项。
  2. 加载程序查找此模块的 API 集转发器,并将其加载到内存中。
  3. 转发器为正在调用的给定函数设置了 API 映射。
  4. 加载程序为给定的设备找到正确的主机二进制文件。

从概念上讲,映射如下所示:

导入的 DLL:feature1.dll

  • Windows 电脑 ->feature1.dll
  • HoloLens ->feature1.dll forwarder ->api-feature1-l1-1-0.dll ->feature1_holo.dll
  • IoT ->feature1.dll forwarder ->api-feature1-l1-1-0.dll ->feature1_iot.dll

最终结果在功能上与直接转发相同,但它是以最大限度地提高应用程序兼容性的方式实现的。

注意

反向转发仅为 Win32 API 图面的子集提供覆盖。 它不允许面向 Windows 桌面版本的应用程序在所有 Windows 设备上运行。