当显式动态链接dll时,使用std::unique_lock会破坏XP的兼容性

Using a std::unique_lock breaks XP compatibility when explicit dynamic linking dll

本文关键字:lock unique 兼容性 XP std 动态 链接 dll 使用      更新时间:2023-10-16

我正在升级一个稍旧的C++项目,以使用C++11(可能是C++14)。我正在尝试使用尽可能多的标准,因为这个项目是跨平台的(Win、Mac、Linux),Boost不是一个选项。

该项目是一个SDK,需要支持Windows XP SP3及更高版本。它使用Visual Studio 2015中的v140_xp CRT。

我发现了一个问题,如果我使用某些C++11函数,如std::unique_lock,CRT会在.dll中添加一个.tls部分(线程本地存储)。尽管,更具体地说,只有当我在unique_lock上调用.lock/.unlock()时,因为似乎只使用unique_lack就可以使其本质上成为一个std::lock_guard,它没有问题。

除了XP和Server 2K3之外,任何版本的Windows上都没有TLS问题,只有当您显式动态链接dll(使用LoadLibrary)时才会出现这些问题。如果您使用.lib文件隐式链接,那么一切都很好,因为隐式.tls会被转换为链接二进制文件,但使用显式链接,您会从LoadLibrary获得Windows错误代码998。

XP上这个隐含的tls问题在这里详细解释:Nynaeve:Thread Local Storage,第6部分

由于我使用的是XP兼容的CRT,我没想到会遇到XP不兼容的情况,比如这样。我(个人)觉得这是CRT XP版本中的一个错误,因为它与XP不完全兼容。

有人碰到这个问题了吗?除了推出我自己版本的所有使用TLS的CRT函数外,还有什么已知的解决方案吗?

由于这是一个SDK,它需要作为旧版本的替代品(我静态链接运行时),并且我不能添加要求我们的客户重写代码以不使用LoadLibrary。

尝试禁用线程安全静态初始化:/Zc:threadSafeInit-

它使用线程本地存储:静态初始化上的访问违规

我打赌std::unique_lock使用静态变量。