C++/WinRT 簡介

 

 

C++/WinRT 是一種完全標準的現代 C++17 語言投影,適用於 Windows 執行階段(WinRT)API,以標頭檔案為基礎實作為庫,設計目的是為您提供一流的存取現代 Windows API 的能力。 使用 C++/WinRT 時,您可以使用任何符合標準的 C++17 編譯器撰寫並使用 Windows 執行階段 API。 Windows SDK 包含 C++/WinRT;它於版本 10.0.17134.0(Windows 10,版本 1803)中推出。

C++/WinRT 是 Microsoft 推薦的 C++/CX 語言投影及 Windows 執行階段 C++ 模板函式庫(WRL)的替代方案。 關於 C++/WinRT 的完整主題清單包含了與 C++/CX 及 WRL 互通及移植的相關資訊。

這很重要

C++/WinRT 中一些最重要的部分,詳見 SDK 支援 C++/WinRTVisual Studio 對 C++/WinRT、XAML、VSIX 擴充套件及 NuGet 套件的支援

另請參閱「我在哪裡可以找到 C++/WinRT 範例應用程式?」。

語言預測

Windows 執行階段 基於元件物件模型(COM)API,設計上可透過語言投影存取。 投影會隱藏 COM 詳細數據,併為指定的語言提供更自然的程式設計體驗。

Windows 執行階段 API 參考內容中的 C++/WinRT 語言投影

當你瀏覽 Windows 執行階段 API 時,點擊右上角的語言組合框,選擇 C++/WinRT,即可查看 API 語法區塊在 C++/WinRT 語言投影中呈現的樣貌。

Visual Studio 支援 C++/WinRT、XAML、VSIX 擴充套件及 NuGet 套件

支援 Visual Studio 的版本,你需要 Visual Studio 2022、Visual Studio 2019 或 Visual Studio 2017(至少版本 15.6;我們建議至少 15.7)。 在 Visual Studio 安裝程式中安裝 通用 Windows 平台 開發工作負載。 在安裝細節>通用 Windows 平台 開發中,如果你還沒檢查過的話,請檢查 C++ (v14x) 通用 Windows 平台 工具選項。 而且,在 Windows 設定>中的隱私與安全Windows 10更新與安全性)>對開發者來說,啟用開發者模式選項(Windows 10:不是側載應用程式選項)。

我們建議你使用最新版本的 Visual Studio 和 Windows SDK,但如果你使用的是 10.0.17763.0 之前隨 Windows SDK 附帶的 C++/WinRT 版本(Windows 10,版本 1809),那麼要使用上述提到的 Windows 命名空間標頭,至少需要你的專案中 Windows SDK 目標版本是 10.0.17134.0(Windows 10,版本 1803)。

Visual Studio 2022 內建了 C++/WinRT 專案和項目範本,讓你能立刻開始 C++/WinRT 開發。 它還內建 Visual Studio 原生除錯視覺化(natvis),可處理 C++/WinRT 投影型別;提供類似 C# 除錯的體驗。 Natvis 會自動套用於除錯建置。 更多資訊請參閱 Visual Studio 原生除錯視覺化,適用於 C++/WinRT

對於較舊版本的 Visual Studio,建議從 Visual Studio 市集下載並安裝最新版本的 C++/WinRT Visual Studio 擴充功能(VSIX)。

  • VSIX 擴充功能提供 Visual Studio 中的 C++/WinRT 專案和項目範本。
  • 此外,它還會提供您針對 C++/WinRT 投影型別的 Visual Studio 原生除錯視覺化(natvis)。

以下章節將介紹 Visual Studio 用於 C++/WinRT 的專案範本。 當你建立一個安裝最新 VSIX 擴充功能的 C++/WinRT 專案時,新的 C++/WinRT 專案會自動安裝 Microsoft.Windows。CppWinRT NuGet 套件Microsoft.Windows。CppWinRT NuGet 套件提供 C++/WinRT 建置支援(MSBuild 屬性與目標),使你的專案能在開發機器與建置代理程式間可攜(建置代理程式僅安裝 NuGet 套件,而非 VSIX 擴充套件)。

或者,您也可以透過手動安裝 Microsoft.Windows.CppWinRT NuGet 套件來轉換現有專案。 安裝 VSIX 擴充功能的最新版本後(或更新至最新版本後),在 Visual Studio 中開啟現有專案,按一下 Project>Manage NuGet Packages...>Browse,在搜尋方塊中輸入或貼上 Microsoft.Windows.CppWinRT,選取搜尋結果中的項目,然後按一下 Install,為該專案安裝套件。 一旦你加入了套件,專案就會獲得 C++/WinRT MSBuild 的支援,包括呼叫該 cppwinrt.exe 工具。

這很重要

如果你有專案是使用(或升級以支援)1.0.190128.4 之前的 VSIX 擴充功能,請參考 VSIX 擴充功能的早期版本。 那一部分包含關於專案設定的重要資訊,你需要知道這些資訊,才能升級到最新版本的 VSIX 擴充功能。

  • 由於 C++/WinRT 使用 C++17 標準的功能,NuGet 套件在 Visual Studio 中設定專案屬性 C/C++>Language>C++ 語言標準>ISO C++17 標準(/std:c++17)。
  • 它也新增了 /bigobj 編譯器的選項。
  • 它新增了 /wait 編譯器選項以啟用 co_await
  • 它指示 XAML 編譯器輸出 C++/WinRT 程式碼生成。
  • 你也可以設定符合 模式:Yes(/permissive-),這會進一步限制你的程式碼必須符合標準。
  • 另一個需要注意的專案屬性是 C/C++>General>將警告視為錯誤。 將此設定為 Yes(/WX)No(/WX-), 視喜好而定。 有時候,由 cppwinrt.exe 工具產生的原始檔會出現警告,直到你將自己的實作加入其中。

按照上述系統的設定,你就能在 Visual Studio 中建立並建置或開啟 C++/WinRT 專案,並部署它。

從 2.0 版本起,Microsoft.Windows.CppWinRT NuGet 套件包含此cppwinrt.exe工具。 你可以將cppwinrt.exe工具指向 Windows 執行階段 的 metadata.winmd () 檔案,產生一個基於標頭檔的標準 C++ 函式庫,將中繼資料中描述的 API 投影給 C++/WinRT 程式碼使用。 Windows 執行階段 的元資料.winmd()檔案提供了描述 Windows 執行階段 API 表面的標準方式。 將 cppwinrt.exe 指向中繼資料後,你可以產生一個程式庫,供任何實作於第二方或第三方 Windows 執行階段 元件中,或實作於你自己的應用程式中的執行階段類別使用。 更多資訊請參閱 Consume API with C++/WinRT

使用 C++/WinRT 時,你也可以使用標準 C++ 實作自己的執行時類別,而不必依賴 COM 風格的程式設計。 對於執行階段類別,您只要在 IDL 檔案中描述您的型別,然後 midl.execppwinrt.exe 就會為您產生實作所需的樣板原始程式碼檔案。 你也可以直接從 C++/WinRT 基底類別來實作介面。 更多資訊請參閱 C++/WinRT 的作者 API

如需透過專案屬性進行設定的 cppwinrt.exe 工具自訂選項清單,請參閱 Microsoft.Windows.CppWinRT NuGet 套件的 readme

你可以藉由專案中已安裝 Microsoft.Windows.CppWinRT NuGet 套件,來識別使用 C++/WinRT MSBuild 支援的專案。

以下是 VSIX 擴充套件提供的 Visual Studio 專案範本。

空白應用程式 (C++/WinRT)

一個針對 Universal Windows Platform (UWP) 應用程式的專案範本,該應用程式具有 XAML 使用者介面。 對於 WinUI 3 桌面應用程式,請改用 Blank App, Packaged (WinUI 3 in Desktop) 範本。

Visual Studio 提供 XAML 編譯器支援,從位於每個 XAML 標記檔案後方的介面定義語言(IDL)(.idl)檔案產生實作與標頭存根。 在 IDL 檔案中,定義任何您想在應用程式的 XAML 頁面中參考的本機執行階段類別,然後建置專案一次,以在 Generated Files 中產生實作範本,並在 Generated Files\sources 中產生存根型別定義。 然後用這些 stub 類型定義作為參考,實作你的本地執行時類別。 請參見將執行時類別分解成 Midl 檔案(.idl)。

Visual Studio 對 C++/WinRT 的 XAML 設計表面支援與 C# 幾乎相當。 在 Visual Studio 中,您可以使用屬性視窗的事件標籤,在 C++/WinRT 專案中新增事件處理程序。 你也可以手動為程式碼新增事件處理程序——更多資訊請參見 C++/WinRT 中「使用代理處理事件 」。

核心應用程式 (C++/WinRT)

一個用於不使用 XAML 的 Universal Windows Platform (UWP) 應用程式的專案範本。 這個範本在 WinUI 3 上沒有對應的版本。

相反地,它使用 C++/WinRT 的 Windows 命名空間標頭來對應 Windows.ApplicationModel.Core 命名空間。 建置並執行後,點擊空白處以新增彩色方格;接著點擊彩色方格並拖曳它。

Windows 控制台應用程式 (C++/WinRT)

一個用於 Windows 桌面版的 C++/WinRT 用戶端應用程式專案範本,具備主控台使用者介面。

Windows 桌面應用程式 (C++/WinRT)

一個用於 Windows 桌面版的 C++/WinRT 用戶端應用程式的專案範本,該應用程式顯示 Windows 執行階段 Windows。Foundation.Uri 放在 Win32 訊息框裡。

Windows 執行階段元件 (C++/WinRT)

元件的專案範本;通常供 通用 Windows 平台 (UWP) 使用。

此範本示範了 midl.exe>cppwinrt.exe 工具鏈,其中會先從 IDL 產生 Windows 執行階段 中繼資料 .winmd,接著再根據該 Windows 執行階段 中繼資料產生實作和標頭檔存根。

在 IDL 檔案中,定義元件中的執行時類別、預設介面以及其他實作的介面。 將專案建置一次,以產生 module.g.cppmodule.h.cppGenerated Files 中的實作範本,以及 Generated Files\sources 中的存根型別定義。 然後用這些存根型別定義作為參考,實作你的元件中的執行時類別。 請參見將執行時類別分解成 Midl 檔案(.idl)。

將已建置的 Windows 執行階段 元件二進位檔及其 .winmd 與使用它們的 UWP 應用程式一併封裝。

VSIX 擴充功能的早期版本

我們建議您安裝(或更新)最新版本的 VSIX 擴充功能。 預設是自動更新。 如果你這麼做了,且你有專案是用 1.0.190128.4 之前的 VSIX 擴充版本建立的,那麼本節包含關於如何升級這些專案以支援新版本的重要資訊。 即使你不更新,這部分的資訊仍然會很有用。

就支援的 Windows SDK 與 Visual Studio 版本,以及 Visual Studio 設定而言,上述 Visual Studio 對 C++/WinRT、XAML、VSIX 擴充套件及 NuGet 套件的支援資訊適用於早期版本的 VSIX 擴充功能。 以下資訊描述了使用早期版本(或升級以支援)專案在行為與配置上的重要差異。

創建於 1.0.181002.2 之前

如果你的專案是在 1.0.181002.2 之前的 VSIX 擴充功能版本中建立的,那麼該版本的 VSIX 擴充功能中就內建了 C++/WinRT 建置支援。 您的專案已在 .vcxproj 檔案中設定 <CppWinRTEnabled>true</CppWinRTEnabled> 屬性。

<Project ...>
    <PropertyGroup Label="Globals">
        <CppWinRTEnabled>true</CppWinRTEnabled>
...

你可以透過手動安裝 Microsoft.Windows.CppWinRT NuGet 套件來升級專案。 安裝(或升級至)最新版的 VSIX 擴充功能後,在 Visual Studio 中開啟你的專案,按一下 Project>Manage NuGet Packages...>Browse,在搜尋方塊中輸入或貼上 Microsoft.Windows.CppWinRT,在搜尋結果中選取該項目,然後按一下 Install,為你的專案安裝該套件。

建立於(或升級為)1.0.181002.2 到 1.0.190128.3 之間的版本

如果你的專案是使用 VSIX 擴充套件的版本介於 1.0.181002.2 到 1.0.190128.3 之間建立的,那麼 Microsoft.Windows。CppWinRT NuGet 套件由專案範本自動安裝到專案中。 你也可能已將較舊的專案升級為使用此範圍內某個版本的 VSIX 擴充功能。 如果你確實這麼做了,那麼——由於此範圍內的 VSIX 擴充功能版本仍然支援建置——你升級後的專案可能已安裝,也可能未安裝 Microsoft.Windows.CppWinRT NuGet 套件。

要升級你的專案,請依照前一節的指示操作,並確保你的專案確實有 Microsoft.Windows。CppWinRT NuGet 套件已安裝。

無效升級配置

在最新版的 VSIX 擴充功能中,如果專案未安裝 Microsoft.Windows.CppWinRT NuGet 套件,則該專案具有 <CppWinRTEnabled>true</CppWinRTEnabled> 屬性是不合法的。 使用此配置的專案會顯示建置錯誤訊息:「C++/WinRT VSIX 不再提供專案建置支援。 請將專案參考新增至 Microsoft.Windows.CppWinRT NuGet 套件。

如前所述,C++/WinRT 專案現在需要安裝 NuGet 套件。

由於該 <CppWinRTEnabled> 元素已過時,你可以選擇性地編輯你的 .vcxproj,並刪除該元素。 這不是絕對必要,但確實是一個選項。

另外,如果你的 .vcxproj 包含 <RequiredBundles>$(RequiredBundles);Microsoft.Windows.CppWinRT</RequiredBundles>,則可以將其移除,這樣一來,你就能在不需要已安裝 C++/WinRT VSIX 擴充功能的情況下進行建置。

對 C++/WinRT 的 SDK 支援

雖然目前僅因相容性考量而存在,但自 10.0.17134.0 版本(Windows 10,版本 1803)起,Windows SDK 包含一個基於標頭檔的標準 C++ 函式庫,用於使用第一方 Windows API(Windows 命名空間中的 Windows 執行階段 API)。 這些標頭都在資料夾 %WindowsSdkDir%Include<WindowsTargetPlatformVersion>\cppwinrt\winrt裡。 根據 Windows SDK 版本 10.0.17763.0(Windows 10,版本 1809),這些標頭會自動在你專案的 $(GeneratedFilesDir) 資料夾中產生。

為了相容性,Windows SDK 也附帶了這個cppwinrt.exe工具。 不過,我們建議您改為安裝並使用最新版本的 cppwinrt.exe,其隨附於 Microsoft.Windows.CppWinRT NuGet 套件中。 該套件,以及 cppwinrt.exe,都在上述章節中描述。

C++/WinRT 投影中的自訂類型

在你的 C++/WinRT 程式設計中,可以使用標準 C++ 語言特性、 標準 C++ 資料型態,以及 C++/WinRT——包括一些 C++ 標準函式庫的資料型態。 但你也會發現投影中有一些自訂資料型態,你可以選擇使用它們。 例如,我們在 Get started with C++/WinRT 的快速啟動程式碼範例中使用 winrt::hstring

WinRT::com_array 是另一種你可能以後會用到的類型。 但你較少會直接使用像 winrt::array_view 這樣的型別。 或者你也可以選擇不使用它,這樣當 C++ 標準函式庫出現等效型態時,就不會有程式碼需要更改。

Warning

如果你仔細研究 C++/WinRT Windows 命名空間標頭,也可能會看到一些類型。 例如 winrt::param::hstring,但也有集合的範例。 這些模式的存在目的是優化輸入參數的綁定,並且大幅提升效能,讓大多數呼叫模式「能正常運作」於相關的標準 C++ 類型和容器上。 這些類型只會在最能發揮價值的情況下由投影使用。 它們高度優化,且不適合一般用途;不要被誘惑去自己使用。 你也不應該使用命名空間中 winrt::impl 的任何東西,因為那是實作類型,可能會變動。 你應該繼續使用標準型別,或是 winrt 命名空間的型別。

另見 「將參數傳入 ABI 邊界」。

重要 API