C++/WinRT 简介

 

 

C++/WinRT 是用于 Windows 运行时(WinRT)API 的完全标准的现代 C++17 语言投影,以头文件为基础的库实现,旨在为你提供对现代 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 的一些最重要部分将在以下章节中介绍:C++/WinRT 的 SDK 支持,以及 Visual 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 进行开发,但如果你使用的是 Windows SDK 中版本低于 10.0.17763.0(Windows 10 版本 1809)的 C++/WinRT,那么,为了使用上述 Windows 命名空间标头,你的项目中的最低 Windows SDK 目标版本需要为 10.0.17134.0(Windows 10,版本 1803)。

Visual Studio 2022 附带内置 C++/WinRT 项目和项模板,以便你可以立即开始使用 C++/WinRT 开发。 它还附带用于 C++/WinRT 投影类型的 Visual Studio 本机调试可视化(natvis),提供类似于 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)。

以下各节介绍了适用于 C++/WinRT 的 Visual Studio 项目模板。 使用安装了最新版本的 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 中打开现有项目,单击 “项目>管理 NuGet 包...”>搜索框中键入或粘贴 Microsoft.Windows.CppWinRT ,选择搜索结果中的项,然后单击“ 安装 ”以安装该项目的包。 添加包后,你将获得对项目的C++/WinRT MSBuild 支持,包括调用 cppwinrt.exe 该工具。

重要

如果您的项目是使用版本早于 1.0.190128.4 的 VSIX 扩展创建或升级的,请参阅 早期版本的 VSIX 扩展。 该部分包含有关项目配置的重要信息,需要了解这些配置才能使用最新版本的 VSIX 扩展。

  • 由于 C++/WinRT 使用 C++17 标准中的功能,因此 NuGet 包在 Visual Studio 中设置项目属性 C/C++>Language>C++ Language Standard>ISO C++17 Standard(/std:c++17)。
  • 它还添加了 /bigobj 编译器选项。
  • 它添加 /await 编译器选项以启用 co_await
  • 它指示 XAML 编译器发出 C++/WinRT codegen。
  • 你可能还想要设置 一致性模式:是(/宽松),这将进一步限制代码符合标准。
  • 要注意的另一个项目属性是 C/C++>General>将警告视为错误。 将此设置为 是(/WX)否(/WX-) 根据需要调整。 有时,cppwinrt.exe 工具生成的源文件会产生警告,需要添加实现才能去除警告。

按照上文所述设置系统后,你将能够在 Visual Studio 中创建和生成或打开C++/WinRT 项目,并将其部署。

从版本 2.0 起, Microsoft.Windows.CppWinRT NuGet 包包括该工具 cppwinrt.exe 。 您可以将 cppwinrt.exe 工具指向 Windows 运行时元数据 (.winmd) 文件,以生成基于头文件的标准 C++ 库,该库可以使 项目 利用元数据中描述的 API,以便从 C++/WinRT 代码中调用。 Windows 运行时元数据 (.winmd) 文件提供了描述 Windows 运行时 API 图面的规范方法。 通过指向 cppwinrt.exe 元数据,可以生成一个库,以便与第二方或第三方 Windows 运行时组件中实现的任何运行时类一起使用,也可以在自己的应用程序中实现。 有关详细信息,请参阅 通过 C++/WinRT调用 API。

使用 C++/WinRT,还可以使用标准C++实现自己的运行时类,而无需使用 COM 样式编程。 对于运行时类,只需在 IDL 文件中描述类型,并midl.execppwinrt.exe生成实现样板源代码文件。 或者,可以通过从 C++/WinRT 基类派生来实现接口。 有关详细信息,请参阅 使用 C++/WinRT开发 API。

有关通过项目属性设置的 cppwinrt.exe 工具的自定义选项列表,请参阅 Microsoft.Windows.CppWinRT NuGet 包 自述文件

可以通过在项目中安装 Microsoft.Windows.CppWinRT NuGet 包来标识使用 C++/WinRT MSBuild 支持的项目。

下面是 VSIX 扩展提供的 Visual Studio 项目模板。

空白应用(C++/WinRT)

具有 XAML 用户界面的通用 Windows 平台(UWP)应用的项目模板。

Visual Studio 提供 XAML 编译器支持,用于从位于每个 XAML 标记文件的接口定义语言(IDL)(.idl)文件中生成实现和标头存根。 在 IDL 文件中,定义要在应用的 XAML 页面中引用的任何本地运行时类,然后在其中生成一次项目以生成实现模板 Generated Files,并在其中 Generated Files\sources生成存根类型定义。 然后,使用这些存根类型定义进行引用来实现本地运行时类。 请参阅 将运行时类整理成 Midl 文件(.idl)

Visual Studio 中对 C++/WinRT 的 XAML 设计界面的支持已经接近与 C# 持平。 在 Visual Studio 中,可以使用“属性”窗口的“事件”选项卡在 C++/WinRT 项目中添加事件处理程序。 您还可以手动将事件处理程序添加到代码中—有关详细信息,请参阅 使用 C++/WinRT 中的委托处理事件

核心应用(C++/WinRT)

不使用 XAML 的通用 Windows 平台 (UWP) 应用的项目模板。

而是使用 C++/WinRT 的 Windows 命名空间标头来处理 Windows.ApplicationModel.Core 命名空间。 生成并运行后,单击空白区域以添加彩色正方形;然后单击彩色正方形以拖动它。

Windows 控制台应用程序(C++/WinRT)

适用于 Windows 桌面的 C++/WinRT 客户端应用程序的项目模板,具有控制台用户界面。

Windows 桌面应用程序(C++/WinRT)

适用于 Windows 桌面的 C++/WinRT 客户端应用程序的项目模板,该模板在 Win32 MessageBox中显示 Windows 运行时 Windows.Foundation.Uri

Windows 运行时组件(C++/WinRT)

组件的项目模板;通常用于从通用 Windows 平台(UWP)使用。

此模板演示 midl.exe>cppwinrt.exe 工具链,其中 Windows 运行时元数据 (.winmd) 是从 IDL 生成的,然后从 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 扩展版本创建的,则C++/WinRT 生成支持内置到该版本的 VSIX 扩展中。 你的项目在 <CppWinRTEnabled>true</CppWinRTEnabled> 文件中设置了 .vcxproj 属性。

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

可以通过手动安装 Microsoft.Windows.CppWinRT NuGet 包来升级项目。 安装(或升级到)最新版本的 VSIX 扩展后,在 Visual Studio 中打开项目,单击 “项目>管理 NuGet 包...”>搜索框中键入或粘贴 Microsoft.Windows.CppWinRT ,选择搜索结果中的项,然后单击“ 安装 ”以安装项目的包。

在 1.0.181002.2 到 1.0.190128.3 版本之间创建或升级

如果项目是使用 1.0.181002.2 和 1.0.190128.3 之间的 VSIX 扩展版本创建的,则项目模板会自动在项目中安装 Microsoft.Windows.CppWinRT NuGet 包。 你可能还将较旧的项目升级到使用此范围内版本的 VSIX 扩展。 如果确实如此,由于此范围内的 VSIX 扩展版本仍存在生成支持,因此升级后的项目可能未安装 Microsoft.Windows.CppWinRT NuGet 包。

若要升级项目,请按照上一部分中的说明进行作,并确保项目已安装 Microsoft.Windows.CppWinRT NuGet 包。

升级配置无效

使用最新版本的 VSIX 扩展时,如果项目未安装 <CppWinRTEnabled>true</CppWinRTEnabled> NuGet 包,则包含 属性的项目是无效的。 具有此配置的项目生成错误消息“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++标准库数据类型。 但是,你还将了解投影中的一些自定义数据类型,你可以选择使用它们。 例如,我们在快速入门代码示例中使用 winrt::hstringC++/WinRT入门。

winrt::com_array 是你可能在某个时候会用到的另一种类型。 但是,你不太可能直接使用像 winrt::array_view这样的类型。 或者,可以选择不使用它,以便在C++标准库中出现等效类型时,不会更改任何代码。

警告

如果仔细研究 C++/WinRT Windows 命名空间标头,还可以查看这些类型。 例如 winrt::param::hstring,但也有集合示例。 它们只是为了优化输入参数的绑定,它们会产生很大的性能改进,并使大多数调用模式“仅有效”用于相关的标准C++类型和容器。 仅在投影能提供最大价值的情况下才使用这些类型。 它们经过高度优化,不适合常规使用;不要想自己使用它们。 也不应使用命名空间中的任何 winrt::impl 内容,因为这些是实现类型,因此可能会更改。 应继续使用标准类型或 winrt 命名空间中的类型。

另请参阅 将参数传递到 ABI 边界

重要 API