windows的技术发展线路非常奇特,在最开始的windows NT时代,windows就是不断推出新的平台和语言,VB就是那个时代的产物,不过VB也算是非常简单一套编程接口了,同时期还有MFC程序,在VC 6.0集了1.0~5.0的大成之后;windows 马不停蹄的开始整新的平台,.NET/COM等技术就出现在那个时代,之后开发环境被称之为VS平台,从2003~2010一共四个主要的版本: VS 2003、VS 2005、VS 2008、VS 2010,同样在VS 2010集大成之后,新的版本VS 2012出现了,它的最大特点是将所有windows 体系的开发环境集成到VS平台中,包括驱动啥的;2019则是将移动端开发也包裹进来了,所以在windows 平台下,使用新技术的风险其实很大,例如接下来的CX技术就是一种过渡技术,而类似这种过渡技术,微软还有很多。
C++/CX 是 C++ 语言的一组扩展,通过这些扩展,可用一种尽可能接近现代 C++ 的惯用语法创建 Windows 应用和 Windows 运行时组件。 使用 C++/CX 通过本机代码编写 Windows 应用和组件,而本机代码可与 Visual C#、Visual Basic、JavaScript 和其他支持 Windows 运行时的语言轻松交互。 少数情况下需要直接访问原始 COM 接口或非异常代码,在这些情况下可使用 Windows 运行时 C++ 模板库 (WRL)。
建议使用/WinRT 作为C++/cx 替代方法。 C++ 它是适用于 Windows 运行时 API 的新标准 C++17 语言投影,从版本 1803 (10.0.17134.0) 起在最新的 Windows SDK 中提供。 C++/WinRT 完全在头文件中实现,旨在提供对新式 Windows API 的优先访问权限。
通过 C++/WinRT,可以使用任何符合标准的 C++17 编译器来同时使用和创作 Windows 运行时 API。 与适用于 Windows 运行时的任何其他语言选择相比,通常 C++/WinRT 的表现更好,生成的二进制文件更小。 我们将继续支持 C++/CX 和 WRL,但强烈建议新应用程序使用 C++/WinRT。
类型系统概述 (C++/CX)
通过使用 Windows 运行时体系结构,可以使用 C++/WinRT、C++/CX、Visual Basic、Visual C# 和 JavaScript 来编写应用和组件。 它们可以直接访问 Windows API,并与其他 Windows 运行时应用和组件进行互操作。 用 C++ 编写的通用 Windows 平台 (UWP) 应用编译为直接在 CPU 中执行的本机代码。 用 C# 或 Visual Basic 编写的 UWP 应用编译为 Microsoft 中间语言 (MSIL) 并在公共语言运行时 (CLR) 中执行。 用 JavaScript 编写的 UWP 应用在 JavaScript 运行时环境中执行。 Windows 运行时操作系统组件本身用 C++ 编写并作为本机代码运行。 所有这些组件和 UWP 应用都直接通过 Windows 运行时应用程序二进制接口 (ABI) 通信。
为了能够以现代 C++ 惯例支持 Windows 运行时,Microsoft 创建了 C++/CX 语言扩展。 C++/CX 提供基本 Windows 运行时类型的内置基类型和实现。 这些类型使得 C++ 应用和组件能够通过 ABI 与用其他语言编写的应用通信。 C++/CX 应用可以使用任何 Windows 运行时类型。 它们还可以创建类、结构、接口以及其他用户定义类型供其他 UWP 应用和组件使用。 只要没有公共可访问性,用 C++/CX 编写的 UWP 应用也能使用常规 C++ 类和结构。
虽然 C++/CX 在语法上与 C++/CLI 相似,因此在许多方面看起来几乎相同,但在语义上却截然不同。C++/CX 代码是本机代码,不需要 CLR。使用 C++/CLI 进行编程可能非常具有挑战性,因为必须同时巧妙地处理两个非常不同的对象模型:具有确定性对象生存期的 C++ 对象模型和垃圾收集 CLI 对象模型。使用 C++/CX 要简单得多,因为基于 COM 的 Windows 运行时可以很好地映射到 C++ 编程语言。
Windows 运行时定义了一个相对简单的低级应用程序二进制接口 (ABI),并要求组件使用通用元数据格式定义其类型。编写本机 Windows 运行时组件并不严格要求使用 C++/CX:完全可以使用 C++ 编写 Windows 运行时组件而无需使用 C++/CX 语言扩展,Visual C++ 2012 包含一个库,即 Windows 运行时 C++ 模板库 (WRL),以帮助简化此过程。作为 Windows 的一部分(在 Windows 命名空间中)提供的许多 Windows 运行时组件都是使用 WRL 编写的。 C++/CX 中没有什么神奇之处:它只是让用 C++ 编写 Windows 运行时组件变得简单得多,并有助于减少使用基于库的解决方案(如 WRL)时必须编写的重复和冗长的代码量。
简单的类
在本文中,我们将通过查看一个简单的 Windows 运行时类来考虑 C++/CX 的基础知识;我们将略过一些细节,但不用担心:我们会在以后的帖子中回来介绍它们。这篇文章中的代码是完整的,但为了简洁起见省略了一些命名空间限定;
好吧。这是我们的简单类:
public ref class Number sealed {
public: Number(): _value(0) {}
int GetValue() {
return _value;
}
void SetValue(int value) {
_value = value;
}
private: int _value;
};
这是一个相当简单的类,但它足以演示 C++/CX 和 Windows 运行时的一些基础知识。除了类声明中的 public ref 和 sealed 之外,这个类看起来与普通的 C++ 类完全一样。这是一件好事:我们的 C++/CX 代码应该看起来与类似的 C++ 代码相似,但应该有足够的不同,以便我们和编译器可以识别出它是不同的。
那么,这个类是密封的、公共的、ref 类究竟意味着什么?ref 类是一种引用类型。Windows 运行时构建在 COM 之上,而 Windows 运行时引用类型实际上是 COM 类类型。每当我们与引用类型对象交互时,我们都会通过指向引用类型实现的接口的指针间接地通过引用进行交互。由于我们从不通过值与引用类型交互,因此它的实现是不透明的:只要其现有接口保持不变,就可以修改其实现而不会影响依赖于它的其他组件,可以添加新功能,但不能删除。
公共类型在定义它的组件外部可见,其他组件可以引用和使用此类型。类型也可以是私有的,这是默认设置,私有类型只能在定义它的组件内引用。C++/CX 组件的 Windows 元数据文件仅包含公共类型的元数据。私有类型的限制比公共类型的限制少,因为私有类型不会出现在元数据中,因此不受 Windows 运行时某些规则的约束。
sealed 仅指定此类不能用作基类。大多数公共 Windows 运行时类型都是密封的。目前,唯一可以解除密封的公共类型是从 Windows::UI::Xaml::DependencyObject 派生的类型;这些类型由 XAML 应用使用。
接口
我上面说过,每当我们与引用类型对象交互时,我们都会通过引用类型实现的接口进行交互。您可能已经注意到,我们的 Number 类似乎没有实现任何接口:它根本没有基类列表。幸运的是,编译器会在这里帮助我们,这样我们的 Number 类就不会毫无用处了。
编译器将自动为我们的类生成一个名为 __INumberPublicNonVirtuals 的接口。顾名思义,这个接口声明了我们的 Number 类型的所有公共非虚拟成员函数。如果我们要在 C++/CX 中自己定义它,它将如下所示:
public interface struct __INumberPublicNonVirtuals {
int GetValue() = 0;
void SetValue(int) = 0;
};
然后转换 Number 类以声明此接口。如果我们的类声明了任何新的公共虚拟成员,即不是基类虚拟成员函数的覆盖或任何虚拟或非虚拟受保护成员,则编译器也会为这些成员生成接口。
请注意,这些自动生成的接口仅声明类明确实现的接口尚未声明的成员。因此,例如,如果我们声明另一个接口:
public interface struct IGetNumberValue {
int GetValue() = 0;
};
并将我们的 Number 类定义为实现此接口,则自动生成的 __INumberPublicNonVirtuals 将仅定义 SetValue 成员函数。