VS2017 C++项目引入Windows.Devices.Enumeration.h编译报错
开发环境与问题背景
- 基础环境:Windows 10操作系统,Visual Studio 2017开发工具,创建遵循C++17标准的MFC项目,配套使用的Windows SDK版本为
10.0.18362.0,开发目标为实现蓝牙LE设备的枚举与连接功能。 - 头文件引入尝试:
- 引入C++/WinRT版本头文件代码:
该类带#include <winrt/Windows.Devices.Enumeration.h>winrt/前缀的头文件存储路径为:C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\cppwinrt\winrt - 引入ABI命名空间版本头文件代码:
该类头文件存储路径为:#include <Windows.Devices.Enumeration.h>C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\winrt
- 引入C++/WinRT版本头文件代码:
故障现象
- 基线编译状态:注释掉上述任意一种WinRT相关头文件的引入语句时,项目可正常编译无报错。
- 引入C++/WinRT版本头文件时的报错:触发大量*Error C2059 syntax error: 'constant'*错误,报错指向微软C++数学库文件
DirectXMathVector.inl中的代码行:XMVECTOR A = XMVectorSelect(g_XMSelect1110.v, V, g_XMSelect1110.v); - 引入ABI版本头文件时的报错:触发大量*Error C2027 use of undefined type 'ABI::Windows::Foundation::Internal::GetAbiType'*错误,报错指向
windows.foundation.collections.h文件中的代码行:typedef typename Windows::Foundation::Internal::GetAbiType<T>::type _abi_type;
待解答疑问
- 为何VS2017搭配C++17标准、版本完全匹配的Windows SDK,无法正常编译微软官方提供的WinRT相关头文件?
- 上述引入WinRT头文件的代码,在VS2019环境下是否可以正常编译通过?
问题原因与结论
VS2017编译失败的核心原因
- 头文件引入顺序冲突是直接诱因
MFC项目默认的头文件加载链会优先引入<windows.h>及关联的DirectXMath、GDI等传统Win32头文件。SDK 10.0.18362.0自带的C++/WinRT头、ABI层WinRT头对Windows基础类型、通用宏的定义和传统Win32头存在严格的顺序依赖:如果传统Win32、MFC头先于WinRT头加载,会直接触发两类问题:- WinRT头内定义的通用宏会污染后续加载的DirectXMath代码,将
DirectXMathVector.inl内的合法标识符替换为常量值,最终触发C2059语法错误。 - ABI层依赖的
GetAbiType模板需要WinRT头内的前置特化声明,提前加载的Win32基础头会打断模板声明链,导致模板实例化时找不到完整类型定义,触发C2027错误。
- WinRT头内定义的通用宏会污染后续加载的DirectXMath代码,将
- VS2017编译器原生支持不足
10.0.18362.0版本Windows SDK内置的C++/WinRT组件正式适配的最低Visual Studio版本为VS2019。VS2017搭载的MSVC编译器对C17标准的实现完整度不足,缺少C/WinRT依赖的部分模板解析、constexpr求值等编译器特性,即使手动调整头文件顺序,也会出现其他兼容性编译错误,无法稳定使用该版本SDK自带的C++/WinRT接口。
VS2019环境下的编译表现
上述引入WinRT头文件的代码,在正确配置的VS2019环境下可以正常编译通过,仅需要提前完成两项配置调整:
- 调整头文件引入顺序:将所有WinRT相关头文件放在MFC、传统Win32头文件的最前面引入,避免宏污染。
- 在项目C/C编译选项中开启
/permissive-标准合规模式,关闭MFC项目默认开启的非标准C兼容扩展。
内容的提问来源于stack exchange,提问作者ehardin
相关产品推荐
相关产品推荐

