使用MinGW构建Qt 5.9.2项目调用WinRT API遇编译错误求助
先给你说句实在话:MinGW 32位和WinRT API的适配确实是个坑,WinRT本身是微软为自家MSVC编译器量身打造的API体系,老版本MinGW(比如Qt 5.9.2配套的MinGW 5.3.0)搭配较高版本Windows SDK时,很容易出现UCRT头文件冲突这类编译报错。下面给你几个针对性的解决思路:
1. 先排查头文件冲突问题
你提到的错误来自UCRT头文件,大概率是MinGW自带的UCRT头文件和Windows SDK里的UCRT头文件发生了冲突。解决办法是调整.pro文件里的INCLUDEPATH顺序,让Windows SDK的UCRT头文件优先被编译器找到:
# 把Windows SDK的UCRT路径放在最前面,避免和MinGW自带头文件冲突 INCLUDEPATH += "C:/Program Files (x86)/Windows Kits/10/Include/10.0.16299.0/ucrt" INCLUDEPATH += "C:/Program Files (x86)/Windows Kits/10/Include/10.0.16299.0/um" INCLUDEPATH += "C:/Program Files (x86)/Windows Kits/10/Include/10.0.16299.0/shared" # 再添加cppwinrt的头文件路径 INCLUDEPATH += "你的cppwinrt解压后的include目录路径"
必要时可以用INCLUDEPATH += -isystem "路径"来强制优先加载指定路径的头文件。
2. 修正.pro文件的WinRT相关配置
除了头文件,链接规则和宏定义也得配置到位,给你一个参考配置:
# 链接Windows SDK的必要库(32位版本对应x86目录) LIBS += -L"C:/Program Files (x86)/Windows Kits/10/Lib/10.0.16299.0/um/x86" LIBS += -lwindowsapp # 定义WinRT相关宏,桌面应用调用WinRT用这个宏 DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP # 指定Windows版本为Win10 DEFINES += _WIN32_WINNT=0x0A00 # cppwinrt需要C++17支持,给MinGW开启C++17并兼容部分语法 QMAKE_CXXFLAGS += -std=c++17 -fpermissive
这里的-fpermissive是为了兼容MinGW对某些C++17语法的不完全支持,避免不必要的编译报错。
3. 调整代码里的WinRT初始化方式
确保你的测试代码里正确初始化了WinRT环境,并且用cppwinrt的语法规范调用API,示例如下:
#include <QCoreApplication> #include <winrt/Windows.Foundation.h> #include <winrt/Windows.Storage.h> #include <QDebug> // 引入cppwinrt的命名空间 using namespace winrt; using namespace Windows::Foundation; using namespace Windows::Storage; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); try { // 初始化WinRT的apartment环境,这一步绝对不能少 init_apartment(); // 测试调用WinRT的图片库API auto picturesFolder = KnownFolders::PicturesLibrary(); qDebug() << "图片库路径:" << QString::fromWCharArray(picturesFolder.Path().c_str()); } catch (const hresult_error& ex) { // 捕获并打印WinRT的错误信息 qDebug() << "WinRT调用错误:" << QString::fromWCharArray(ex.message().c_str()); } return a.exec(); }
如果调用的是需要权限的WinRT API(比如访问文件系统),还得注意系统权限配置,桌面应用可能不需要打包,但必要时可以调整系统的权限设置。
4. 终极方案:切换到MSVC编译器
如果上面的方法都搞不定,真心建议你换成Qt 5.9.2的MSVC 32位版本来开发。WinRT API对MSVC的支持是原生级别的,不会有这么多兼容性问题,配置起来也简单得多——只需要安装对应的MSVC版本Qt套件,然后在.pro里添加cppwinrt路径和必要的库链接就行,基本不会出现UCRT头文件这类奇怪的错误。
内容的提问来源于stack exchange,提问作者Paweł Skorupiński

