c++ - thread_local unordered_map 加上 AccessibleObjectFromWindow 不在 WinXP 中运行
问题描述
我正在使用 VC++ 2015 编译以下程序。
#include <oleacc.h>
#include <unordered_map>
#pragma comment(lib,"User32.lib")
#pragma comment(lib,"Oleacc.lib")
thread_local std::unordered_map<int, int> something ;
int main( int argc, char* argv[] ){
MessageBox(0, "Program started", "Test program", MB_SETFOREGROUND) ;
IAccessible* test ;
AccessibleObjectFromWindow(GetForegroundWindow(), OBJID_WINDOW, IID_IAccessible, (void**)&test) ;
}
命令行:
cl test.cpp /EHsc /link /MACHINE:x86 /entry:mainCRTStartup /subsystem:windows,5.1
程序显示一个消息框并退出。它适用于除 Windows XP 之外的所有 Windows 版本,在这些版本中,双击程序图标时没有任何反应。
没有错误消息或任何表明程序失败的迹象。它什么也不做。它会在任务管理器中显示几分之一秒,然后消失。
必须存在以下两个元素才能使程序在 Win XP 中失败。
thread_local
unordered_map
全局范围内的A。- 打电话给
AccessibleObjectFromWindow
如果我进行以下任何更改,该程序确实可以在 XP 中运行:
- 更改
unordered_map
为std::map
- 删除
thread_local
关键字 - 将
thread_local
变量移入内部main
- 删除对
AccessibleObjectFromWindow
是否有任何命令行参数可以传递给编译器/链接器,以便程序在 WinXP 中运行?
更新:
如果我添加/MD
到命令行(即使用操作系统中安装的运行时),WinXP可以成功运行程序。
这表明问题是 Windows XP 和 VS2015 嵌入到可执行文件中的 MSVC 运行时库之间存在某种不兼容(我也尝试使用 VS2019,但没有区别)。
我尝试通过 GUI 构建项目并选择Windows XP (v140_xp)作为平台工具集,但问题仍然存在。
我想我唯一的选择是更改unordered_map
为map
. thread_local
或者以某种方式摆脱。
解决方案
尝试添加/Zc:threadSafeInit-
到编译器命令行。
来自VC++ 2015 的线程安全本地静态初始化:
线程安全的静态局部变量在内部使用线程局部存储 (TLS) 以在静态已经初始化时提供高效执行。此功能的实现依赖于 Windows Vista 及更高版本操作系统中的 Windows 操作系统支持功能。 Windows XP、Windows Server 2003 和较早的操作系统没有此支持, 因此它们无法获得效率优势。这些操作系统对可以加载的 TLS 部分的数量也有下限。超过 TLS 部分限制可能会导致崩溃。如果这是您的代码中的问题,尤其 是必须在旧操作系统上运行的代码中,请使用 /Zc:threadSafeInit- 禁用线程安全初始化代码。
推荐阅读
- c# - Observable() 操作后删除文件
- html - 从excel VBA发送短信
- java - java中的@Override注解如何检查方法的拼写错误?
- asp.net - 如何使用 c#3 使用 asp.net 在特定网格视图单元格上进行自动换行
- python - 如何使用 selenium 切换到弹出窗口
- sql - Oracle 等价于 information_schema.tables
- excel - Excel 函数(员工时间表):每天减去一小时的午餐时间
- ios - 无法在 iOS 邮件中使用 WorkMail 盟友地址
- javascript - 如何在 php 中上传(和可视化)图像而不刷新页面?
- html - CSS Grid level 2 中的子网格概念现在是否可以在浏览器中使用?