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