长久以来,在Windows桌面端需要调用系统级能力的时候,我们只能引入 Windows.h 然后任凭上个世纪的拗口API摆布。这往往意味着:

LPCSTR/LPSTR/LPCWSTR/LPWSTR/wchar_t/……

人们孜孜不倦的发明各种奇技淫巧,只是为了将这些智障字符串在std::string/std::wstring或者char*之间互相转换。到最后所有人都会从Stack OverFlow上面摘抄代码,放弃治疗。

CreateWindowA/CreateWindowW

同时为了兼容两种字符集,每个涉及到字符串的API都是成对出现。

需要开辟缓冲区的API,可能需要反复调用

C-API的通病了,先返回个buffer size,第二次再传入缓冲区指针。一搞不好就是越界访问。

WinRT at the rescuer

好在从Windows 8开始,微软搞了Windows Runtime(WinRT),基于 COM 协议封装的一套API。除了使用(生态封闭的)C#语言来消费这套接口以外,微软还为其打造了一套C++方言——C++/CX。

基本上,这就是后来C++/WinRT的雏形,但是仍然需要用手动的方式进行引用计数等等一系列繁琐操作。况且方言毕竟是方言,使用C++/CX并没有特别大的优势。额外增加的符号和关键字也使得基于这类语言的编程从技术栈上看相当的不伦不类。

好在2017年终于有人意识到C++已经早已不是原来那个C with Class的语言了,充分利用那些高级特性,完全可以构造一套便捷优雅的接口。更何况,与其自立门户搞什么小众语言,不如讨好大众,就用C++将桌面平台重新开放给广大开发者们。就凭现代C++的易用性,比传统的Win32接口高到不知道哪里去了。

C++/WinRT注定要成为Windows平台开发的新基石。

字符串一定使用WinRT后体感提升最大的方向之一。只需要简单的to_string和to_hstring两个接口,就能处理大部分字符串相关接口的传参问题。错误处理也是同理。

另一个极大提升体验的操作是智能指针。一切WinRT提供的对象都是封装好的智能指针,从而再也不需要使用显式的引用管理。智能指针也能极大减少编写析构函数的时间,从而减少内存相关问题的隐患。

拥有CPP20新的异步特性加持,耗时操作的接口也得以异步函数的形态提供。不想被异步污染整个同步架构的话,使用get方法也能相当便捷的串行化。比起那些“一处异步,处处异步”的智障语言好太多了。

A Year Later

上面的部分写与一年前,然而今非昔比,C++/WinRT也在无可救药的变得过于复杂。一方面Windows虽然一直在“大力推进”WinUI3的开发工作,但其仍然没有给开发者提供一个能与Electron甚至Flutter抗衡的开发环境。现如今Windows11都已经快预览了一年了,美轮美奂的Mica材质仍然还没实装到SDK中,潦草的第一方支持之下,WinUI3还能拿什么来与上述两个方案抗衡,着实让人担忧。

另一方面,微软命名部门日常污染关键词的老毛病又犯了,C++/WinRT还不够,未来将是C#/WinRT,Windows App SDK以及.net(DotNet) core大混战的刺激场面,希望桌面端的开发者对搜索引擎的使用也要再学习一个,提升一些知识水平。