C++/WinRT 到底是什么?

Ayd*_*ili 20 c++ windows c++-winrt

我一直在网上搜索。我明白

C++/WinRT 作为标准 C++17 头文件库提供

但它到底是什么?它是古老的 Win32 API 的新的面向对象的替代品吗?它是 Windows 上 Qt 框架的替代品吗?它是一个网络库吗(大多数例子似乎都是关于网络的)。它是一个 GUI 框架吗?它是编写新 Windows 应用程序的首选方式吗?它是臭名昭著的 MFC 库的替代品吗?

IIn*_*ble 20

C++/WinRT 是Windows 运行时 (WinRT) API语言投影。Windows 运行时1是 Windows 用于公开其 API 的基础结构。它旨在成为基于 C 的平面 Win32 API 的继承者(尽管您可以同时使用 Windows 运行时和 Windows API)。

C++/WinRT(与任何其他语言投影一样)将基于 COM 的 Windows 运行时接口转换为自然、惯用的语言模式,在 C++/WinRT 的情况下,C++'。最值得注意的是它做了三件事:

  • 它通过将引用计数绑定到智能指针的对象生命周期来自动化 COM 对象的资源管理。
  • 它在 COM 的错误报告(基于HRESULT返回值)和基于 C++ 异常的 C++ 错误报告之间进行转换。
  • 它将基于 Windows 运行时的异步模式映射IAsyncInfo到 C++20 协程。

使用(当时是新的)Windows 运行时作为交付渠道发布了多项新技术。最明显的是新的 UI 框架。据我所知,它仍然没有名字。它曾经被命名为“Metro”“Modern UI”“Fluent Design”。我听说过的最新术语是Windows 演示平台。它使用 Direct2D 呈现,并且通常使用 XAML 进行创作。

虽然经常与 Windows 运行时混为一谈,但 Windows 演示平台只是该技术的一个客户端。它不是 Windows 运行时本身的一部分。

另一个重点是,Windows 运行时不强制要求使用任何特定的 UI 库或框架。它在经典桌面应用程序(直接用 Win32、MFC、WTL、wxWidgets 等编写)或 .NET 应用程序(Windows 窗体、WPF)中同样有效,就像在具有 XAML/Windows 演示平台 UI 的应用程序中一样.


1 使用现代化版本的 COM 公开 Windows 运行时。组件可以被多种语言使用和创作。组件使用符合ECMA-335 的元数据(.winmd 文件)对其公共接口进行编码。该技术本身不依赖于 .NET 或 CLR。

  • 我不知道它的实际使用范围有多大。我相信它已经取代了微软内部以前的 WRL 和 C++/CX 的一切。在 Microsoft 之外,我还没有见过表明使用 C++/WinRT(甚至只是本机 Windows 运行时开发)的工作机会。MS 在解释什么是 Windows 运行时、语言投影如何适应该图景以及 UWP 与 Windows 运行时有何不同方面做得非常糟糕。似乎每个人都认为 Windows 运行时是托管代码,最好与 C# 一起使用,并且需要针对 UWP(这三个都是错误的)。 (5认同)
  • @jul:这些信息分散在 MSDN 上。对我来说,最有启发性的花絮来自[组件对象模型](https://learn.microsoft.com/en-us/windows/win32/com/the-component-object-model):*“COM [ ...] 不是面向对象的语言,而是一种标准。[...] COM 的唯一语言要求是,代码是用可以创建指针结构的语言生成的,并且可以显式或隐式地通过以下方式调用函数:指针。面向对象语言 [...] 提供了简化 COM 对象实现的编程机制 [...]。”* (3认同)
  • 它是 Win32 API 的完全替代品吗?除了您在答案中提供的链接之外,我没有看到任何人谈论 C++/WinRT。 (2认同)
  • 那么现在Windows开发的主要方式是什么呢?还是Win32?其他一些 C++ 库/API?是不是类似C#以及相关的库之类的东西? (2认同)
  • 这实际上取决于您的需要。对于我的个人工具,我通常只使用经典的桌面 UI、主对话框、在 .rc 文件中编写脚本,以及大量 C++/WinRT 来与 Windows 运行时交互。还有相当多的 Win32 API 调用,要么是因为 Windows 运行时中没有等效的调用,要么只是因为在 Windows API 中打开文件不那么麻烦。您可以将所有这些混合在一个应用程序中,甚至是命令行应用程序中。将 XAML 与 C++/WinRT 结合使用仍然很麻烦。当它起作用时,它很有趣,但它经常不起作用。 (2认同)
  • 经典桌面 UI 是什么意思?你的意思是直接的Win32代码吗?原谅我的无知。 (2认同)
  • 正确,只是普通的基于对话框的 Win32 应用程序,在“wWinMain”内有一行代码,它返回“DialogBoxParamW”返回的任何内容。对我来说,这仍然是启动并运行带有 GUI 的 C++ 应用程序的最快方法。是的,只要您在 Windows 10 上运行,您就可以访问通过 Windows 运行时公开的所有功能(除了少数例外,需要应用程序标识,并且需要在应用程序容器中运行)。 (2认同)
  • @IInspectable 关于该主题,MS 在解释 COM 方面也做得很差。如果他们发布(并实施)了一个规范,那么谁知道我们现在会处于什么位置?相反,我们“阅读 Box 的书,并做 VS 似乎做的任何事情”。我必须通过口耳相传来学习它的基本原理 (2认同)
  • @user1 嗯,它的基础知识在 22 年里没有改变,你可以在任何地方学习基础知识并浏览特定功能的在线文档 (2认同)
  • @jul:COM仅支持ABI级别的[接口继承](https://learn.microsoft.com/en-us/windows/win32/com/iunknown-and-interface-inheritance)。这并不对*实施*施加限制。用 C++ 实现的 COM 对象可以自由地从基类(如“winrt::implements”类模板)派生,只要它为继承的*接口*维护 COM 兼容的 v 表布局。WinRT 仍然使用 90 年代中期发明的相同 COM。C++/WinRT(对某些人来说)方便地隐藏了所有 ABI 级别的机制,将“经典”WinRT API 映射到熟悉的 C++ 习惯用法。 (2认同)

Chu*_*urn 19

IInspectable 的答案实际上是正确的,但更多的上下文也可能有所帮助......

C++/CX(又名 Visual C++/ZW开关)、Windows 运行时库 (WRL) 和 C++/WinRT 基本上都做同样的事情:提供一种机制,用于从 C++ 调用“Windows 运行时”样式的 API 和类型以及用于创作“Windows 运行时” " 样式 API 和类型。

OP 问题涉及一个更基本的问题:Windows 运行时 API 的重点是什么?

最初的 Win32 API 是为本地代码世界设计的,大多数程序是用 C 或 C++ 编写的。创建组件对象模型 (COM) 是为了使用相同的基本应用程序二进制接口 (ABI) 处理运行时版本控制(和许多其他功能)。C++ 是使用 COM 的一种更自然的方式,但您仍然可以通过各种宏在技术上使用 C,而不能。

.NET 和其他托管语言后来出现,并使用不同的调用机制。您可以使用本机互操作来访问 Win32 或 COM API,但它们通常不会以非常“C# 友好”的方式工作。已经创建了各种“包装程序集”,提供了一种更自然的方式来访问 C/C++ API 和类型。

随着互联网特别是万维网的发展,另一类应用程序是使用 HTML5+JavaScript 编写的。他们没有对 Win32 或 COM API 的任何特定访问权限,因此编写了特殊的模块和库来弥补功能差距。

因此,考虑到所有这三种主要方法,“Windows 运行时”风格是一种将 COM 的功能与 .NET 的反射丰富的元数据相结合的方法。这个想法是一个 API 可以被编写一次,并且可以被 C++、C# 和 HTML5+JavaScript 使用。

当然,除了能够调用 ABI 之外,使用 API 还存在很多问题,而且每种语言范式都大不相同,但从系统编程的角度来看,这就是重点。

使用其本身具有三个基本“appmodels” Windows运行时API的一个“万能Windows平台”:XAML,DirectX和XAML +的DirectX。如果这些应用程序是用 C++ 编写的,那么这些应用程序可以大量使用 C++/WinRT,但您也可以使用 Win32 桌面应用程序中的 Windows 运行时 API。

WRL 实际上是“ATL 2.0”,并且是 C++ 与 Windows 运行时 API 互操作的解决方案的首次尝试。您可以使用它来使用和创作 Windows 运行时类型,但这是大量的手动工作,并且没有很好地公开记录。Win32 桌面应用程序中的主要实用程序是Microsoft::WRL::ComPtr智能指针。

如果您想知道为什么 C++/CX 存在,请参阅此博客系列。它旨在成为 C++ 的易于使用的模型,但它经常与托管 C++(它使用相同的保留关键字,但与托管 C++ 或 .NET 完全无关)并不受其他编译器支持。

如果您想了解更多关于 C++/WinRT 的一般原因,请参阅这篇MSDN 杂志文章。这是一种更加 C++ 友好的方式来使用 Windows 运行时 API,可移植到其他非 Microsoft 编译器,并且越来越多地在内部和外部用于 Windows 运行时开发。它确实需要 C++17 语言功能,因此会努力提高 C++ 编译器的质量。

  • “WRL 确实是‘ATL 2.0’”,这说明了一切![C++/WinRT 如何表示 ABI 类型](https://devblogs.microsoft.com/oldnewthing/20200924-00/?p=104275) 还提供了易于阅读的摘要。 (2认同)