Windows API 集合

重要

本主題中的資訊適用於所有 Windows 10 版本及更新版本。 以下將這些版本統稱為「Windows」,並在必要時特別指出任何例外情況。

所有版本的 Windows 都會共用稱為核心 OS 的作業系統 (OS) 元件通用基底(在某些情況下,此通用基底也稱為 OneCore)。 在核心OS元件中,Win32 API 會組織成稱為 API 集合的功能群組。

API 集合的目的是提供一種架構上的分離,連結實作特定 Win32 API 的主機 DLL 與該 API 所屬的功能性合約。 API 集合在實作和合約之間提供的分離為開發人員提供了許多工程優勢。 特別是,在您的程式代碼中使用 API 集合可以改善與 Windows 裝置的相容性。

API 集合會特別解決下列案例:

  • 雖然 Windows 32 API 的完整範圍在 PC 上被支援,但只有部分 Win32 API 可用於其他 Windows 裝置,如 HoloLens、XBOX 及其他裝置。 API 集合名稱能讓你有穩定的查詢,讓你的應用程式能在執行時偵測目前裝置是否有該功能可用。 查詢本身是由 IsApiSetImplemented 函式執行。

  • 某些 Win32 API 實作存在於具有不同 Windows 裝置不同名稱的 DLL 中。 在偵測 API 可用性與延遲載入 API 時,使用 API 集合名稱而非 DLL 名稱,無論 API 實際實作地點,都能提供正確的實作路徑。

如需詳細資訊,請參閱 API 集合載入器作業 和 偵測 API 集合可用性。

API 集合和 DLL 是同一回事嗎?

不——API 集合名稱是識別 合約,而非檔案。 執行時,載入器會透過目前裝置上的 API 集合架構解析該合約,並將參考路由至承載該實作的 DLL。 這是一種隱藏實作細節的技術,也就是說,身為呼叫端的您不必確切知道究竟是哪個模組提供這些資訊。

這項技術可讓模組在不同的 Windows 版本和版本上重構(分割、合併、重新命名等等)。 而且你的應用程式仍然會連結,執行時也會被導向正確的程式碼。

那麼,為什麼 API 集合的名稱中有 .dll ? 原因是 DLL 載入器實作的方式。 載入器是作業系統中載入 DLL 和/或解析 DLL 引用的部分,並透過模組名稱的拼寫來識別要載入的內容,該模組名稱拼寫方式與匯入表中檔案名稱的拼法相同。 API 集合名稱遵循相同的慣例,以確保它們能放在相同的位置。

載入器會識別以 api- 或 ext- 開頭的名稱,並將其路由到 API 集合執行時,這是載入器的延伸,透過結構解決合約。 從那時起,名稱會依照 API 集命名規則解析,而非檔案名稱,因此 .dll 後綴不會是被解析合約名稱的一部分。

你可以把 API 集合名稱傳給 LoadLibrary,或用作延遲載入目標。 當當前裝置的結構模式將該合約映射到可用主機時,操作即成功;電腦上不一定有這個名稱的正式檔案。 如果該契約未對應到目前裝置,直接呼叫 LoadLibrary 就會失敗。 延遲載入的參考則行為不同:程序仍會載入,且缺席會在 API 呼叫時稍後浮現。

不管怎樣,成功的連結或載入本身並不代表有實作存在。 要判斷這點,請參見 「偵測 API 集合可用性」。

連結傘式程式庫

為了更輕鬆地將程式代碼限制為核心OS中支援的Win32 API,我們提供一系列的 傘式連結庫。 傘式函式庫讓你可以連結單一函式庫,而不是為每個呼叫的 API 識別個別匯入函式庫。

更多細節及選擇符合你目標的傘式函式庫,請參見 Windows 傘式函式庫。

API 集合合約名稱

API 集合以合約名稱識別,該合約名稱遵循函式庫載入器所識別的慣例。

所有合約名稱皆共享以下慣例:

  • 名稱可能以字串 api- 或 ext- 開頭。
  • 名稱的主體可以是英數位元或虛線 (-)。 波浪號(~)只會作為群組名稱前方的分隔符號出現。
  • 名稱不區分大小寫。

合約名稱有兩種形式,你可能會遇到其中一種。

版本化合約名稱以序列 l<n-n-n>><>< 結尾,其中 n 包含十進位數字——例如, 。 ext-ms-win-core-samplefeature-l1-1-0 尾號標示合約的一個特定版本,而此形式的名稱應視為該版本的不可更改識別碼。

合約別名不含版本,例如:api-win-core-samplefeature。 它識別的是契約本身,而非單一版本。 當合約將其個別可用的功能組織成 具名群組 時,可透過在合約別名後附加群組名稱,並以波狀符號分隔,來定址該群組:api-win-core-samplefeature~AdvancedOperations

samplefeature此處使用的名稱是虛構 Windows 元件的說明性名稱。

api- 與 ext- 前綴

前綴是一種命名慣例。 它最初的目的是區分每個合格版本中都存在的合約(api-)與可能缺失的合約(ext-)。 這種區分並不總是被一致地套用,合約的角色可以隨時間改變,而合約名稱不會被更改。

載入器不會賦予前綴任何意義;它用相同的規則解析 API 和ext 名稱。 不要從前綴推斷可用性。 請改為查詢——參見 偵測 API 集可用性。

使用合約名稱

有兩種不同的操作會接受合約名稱。

載入器操作——如 LoadLibrary 或 P/Invoke——會將合約名稱置於 DLL 模組名稱通常出現的位置。 附加 .dll 符號在那種語境下是慣例,但 API 集合名稱解析不要求,也不包含在合約名稱中。 使用合約名稱取代實體 DLL 模組名稱,以確保無論 API 實際在目前裝置哪裡實作,都能正確路由到實作。 磁碟上不需要有那個合約名稱的檔案。

可用性查詢範例 慣例省略 .dll 後綴,並使用與 API 位址相符的形式:

API 介面 查詢形式 Example
命名群組 <contract>~<group> api-win-core-samplefeature~AdvancedOperations
預設群組 合約別名,不含 ~Default api-win-core-samplefeature
版本化合約 完整版本化合約名稱 ext-ms-win-core-samplefeature-l1-1-0

群組名稱不能與版本化合約名稱合併。

識別 Win32 API 的 API 集合

若要識別特定 Win32 API 是否屬於 API 集合,請檢閱 API 參考檔中的需求數據表。 如果 API 屬於 API 集合,文章中的需求數據表會列出 API 集合名稱和 API 第一次引入 API 集合的 Windows 版本。 如需屬於 API 集合的 API 範例,請參閱下列文章:

如果 API 標頭有提供 Is<APIName>Present 輔助函式,測試可用性時就優先使用該輔助函式。 它已經包含承載該 API 的 API 集合或群組的正確名稱。 如需詳細資訊,請參閱 偵測 API 集可用性。

本節中