|
最近在做 ESP32-C3 与 Windows 端 BLE 通信时,我顺手把 Windows 端切到了 C++/WinRT。
这篇文章记录一个最小可运行路径:从 Visual Studio 配置开始,到成功调用 WinRT 的 的函数并启动。
本文重点讲清楚这几件事:
- VS 里怎么配置 C++/WinRT
- 代码里为什么要写 #pragma comment(lib, "windowsapp.lib") 和 #pragma comment(lib, "runtimeobject.lib")
- 这两行和项目属性里的“附加依赖项”是什么关系
- include、init_apartment、Uri 这几行代码分别是什么意思
- WinRT 的优势是什么
一、先说结论:C++/WinRT 不一定要专用模板
我一开始也在找“C++/WinRT 专用模板”,后来发现其实不必。
直接新建一个普通的 C++ 控制台项目也可以,只要工具链和链接配置正确。
推荐路线:
- 新建 Console App(C++)
- 平台选 x64
- C++ 语言标准至少 C++17,建议 C++20
- 加 WinRT 头文件
- 链接 WinRT 相关库
二、Visual Studio 配置位置
1. C++ 语言标准
项目 -> 属性 -> 配置属性 -> C/C++ -> 语言 -> C++ 语言标准
建议选择:
ISO C++20 标准
或至少 C++17
我之前踩过一个坑:命令行把 /std:c++20 打成了 /std:c+=20,结果所有报错都在提示“需要 C++17”,实际是参数写错了。
2. 链接库配置
项目 -> 属性 -> 配置属性 -> 链接器 -> 输入 -> 附加依赖项
添加两项:
windowsapp.lib
runtimeobject.lib
这两行代码是给链接器下指令:
#pragma comment(lib, "windowsapp.lib")
#pragma comment(lib, "runtimeobject.lib")
作用等价于你在“链接器 -> 输入 -> 附加依赖项”里手动添加库。
也就是说,这两种方式本质上都在做同一件事:告诉链接器去链接哪些库。
它们的关系
- 项目属性方式:配置集中在工程里,团队协作更直观
- pragma 方式:配置写在源码里,单文件示例更方便搬运
建议
- 学习和示例阶段:pragma 很方便
- 团队项目:更推荐项目属性统一管理
- 两者二选一即可,避免重复维护
四、最小示例代码(可直接运行)
下面这段是我用于验证 C++/WinRT 环境是否正常的最小例子:
点击查看代码
#include <iostream>
#include <winrt/base.h>
#include <winrt/Windows.Foundation.h>
#pragma comment(lib, "windowsapp.lib")
#pragma comment(lib, "runtimeobject.lib")
int main()
{
winrt::init_apartment(winrt::apartment_type::multi_threaded);
winrt::Windows::Foundation::Uri uri(L"https://learn.microsoft.com/zh-cn/windows");
std::wcout << L"WinRT Uri Host: " << uri.Host().c_str() << L"\n";
std::wcout << L"WinRT Uri Path: " << uri.Path().c_str() << L"\n";
return 0;
}
如果输出了 Host 和 Path,说明环境已经通了。
五、逐行解释关键代码
- include 头文件
#include <winrt/base.h>
#include <winrt/Windows.Foundation.h>
- winrt/base.h:C++/WinRT 基础类型和初始化能力
- winrt/Windows.Foundation.h:引入 Windows.Foundation 命名空间里的类型,比如 Uri
注意大小写和拼写,Foundation 很容易拼错成 fundation,错一个字母就会报找不到头文件。
- 初始化线程单元
winrt::init_apartment(winrt::apartment_type::multi_threaded);
这一步是初始化 WinRT 运行环境(底层可理解为 COM Apartment 初始化)。
不初始化就直接调用 WinRT API,很多场景会出问题。
multi_threaded 的含义是使用多线程单元模式,控制台程序常用这个就够了。
3. 创建 Uri 对象
winrt::Windows::Foundation::Uri uri(L"https://learn.microsoft.com/zh-cn/windows");
这行代码就是在用 WinRT 的 Uri 类型解析地址。
后续可以直接取 Host、Path、Query 等属性,不需要自己手写字符串解析。
C++/WinRT 的优势(为什么值得学)
原生性能
C++ 直接调用 WinRT API,性能和资源控制都很好。
类型安全
相比旧式 ABI 调用,C++/WinRT 提供了更现代、类型安全的接口。
来源:https://www.cnblogs.com/duwenlong/p/19897686 |