【问题标题】:Can I link a static library built with the v120_xp toolset into an EXE/DLL built with the v120 toolset in VS2013?我可以将使用 v120_xp 工具集构建的静态库链接到使用 VS2013 中的 v120 工具集构建的 EXE/DLL 中吗?
【发布时间】:2014-02-26 12:55:57
【问题描述】:

我正在处理一个包含四组本机 C++ VS2013 项目的大型代码库。我将这些集合称为 A、B、C 和 D。

集合 A 和 B 中的项目生成 C++ 静态库 (.lib)。集合 C 和 D 中的项目生成 DLL 和可执行文件。

集合 C 中的项目仅链接到集合 A 中的静态库,而集合 D 中的项目链接到来自集合 A 和集合 B 的静态库

              C (.dll, .exe) ----> A (.lib)
                                   ^
                                   |
                                   |
                                   D (.dll, .exe) -----> B (.lib)

我有以下要求:

  1. 集合 C 中的项目生成的那些 DLL 和 EXE必须在 Windows XP 和 Windows 7 上运行
  2. 另一方面,那些由 D 组中的项目生成的 DLL 和 EXE, 不需要在 Windows XP 上运行

我想做的是使用v120_xp 平台工具集构建集合A 和C 中的项目,以及使用v120 平台工具集构建集合B 和D 中的项目:

                (WinXP, Win7)
                 C [v120_xp] ----> A [v120_xp]    
                                   ^
                                   |
                                   |
                                   D [v120] -----> B [v120]
                                 (Win7 only)

I believe this should not be a problem for projects in set C,但我关心的是 D 组中的项目。

我尝试为几个小项目执行上述操作,似乎一切正常,但是这在一般情况下是否保证安全?


我的研究:

this question 中的第 2 点)问的问题与我问的几乎相同,但针对 VS2012。它没有收到答案。

This answer(同样,对于 VS2012)提到:

长话短说,混合使用 v110 和 v110_xp 工具集构建的模块不是问题。

另一方面,This other answer to the same question 说:

官方不支持混合 v110_xp 可执行文件和 v110 库。

【问题讨论】:

    标签: c++ linker windows-xp visual-studio-2013 static-libraries


    【解决方案1】:

    我真的不明白这个问题如何涵盖新领域。 Steve-o 引用的 Microsoft 支持人员告诉他的所有内容都是准确的。他的结论不是,你当然可以打电话给微软支持并寻求帮助。这是浪费钱,他们会明确告诉你必须选择 v120_xp 工具集。

    这真的很简单,如果您希望可执行文件在 XP 上运行,那么使用 v120_xp 工具集是一项硬性要求。如果你不这样做,那也没关系。 真正重要的唯一设置是链接器的 /subsystem 选项。从 VS2012 开始,工具集对此进行了设置,以便您的可执行文件包含 6.0 作为所需的子系统。从 Vista 开始的 Windows 一代。并且使用 v120_xp 会更改此设置,使用 4.0 的旧值。从 NT 4.0 开始的一代。 XP是5.0代,它会拒绝运行子系统设置为6.0的程序

    确实很重要,操作系统会查看它并决定打开哪个appcompat shims。在标头中将子系统设置为 4.0 时,Windows 假定您编写代码时没有考虑 Aero。一些 appcompat 垫片专门用于打开谎言,使您的程序相信它仍然在经典用户界面上运行。宽窗口边框是一个重要的 appcompat 问题,CreateWindowEx() 调用采用外部窗口大小,但许多程序确实关心客户区的大小。

    您应该担心的是在您的进程中运行多个版本的 CRT。当模块不使用相同的版本时,往往会发生相当糟糕的事情。就像 DLL 中的函数一样,它返回标准 C++ 库类对象,如 std::string。当客户端代码不使用与 DLL 相同的分配器时,它会调用失败,它不能可靠地销毁对象。或者更糟糕的是,如果它使用具有完全不同布局的 std::string 对象的旧版 C++ 库。尤其是 C++11 中的变化使这成为一个常见的事故。

    在您的情况下,您不必担心。当您使用 /MD 构建时,v120 和 v120_xp 工具集使用完全相同的 CRT 版本 msvcr120.dll 和 msvcp120.dll(您应该这样做)。该 CRT 可以在 XP 以及更高版本的 Windows 上运行,它使用 GetProcAddress() 动态绑定到可能不可用的 winapi 函数。这不是什么新东西,以前的 CRT 版本已经为 FlsAlloc() 之类的 winapi 函数做了这个,还有更多。新增内容涉及对线程和语言环境的支持。

    【讨论】:

    • It is really rather straight-forward, if you want the executable to run on XP then using the v120_xp toolset is a hard requirement。我同意。我的问题确实表明我关心的是那些不需要需要在WinXP上运行的二进制文件(因此是用v120工具集构建的)链接使用v120_xp 工具集构建的静态库(这是因为这些库还与其他确实 需要在XP 上运行的二进制文件链接,并且它们本身是使用v120_xp 工具集构建的)。所以问题是:我可以将v120_xp lib 链接到v120 exe/dll 吗?
    • 我已经完全没有办法说“这不是问题”。关于它是如何工作的,你有一些不明白的地方,我不知道那可能是什么。
    • 抱歉听起来很厚重,并且不知道你提到的一些事情,但如果它很简单而且不是问题,我希望你会引用我问题中唯一包含一个问号并写下“是的,它非常安全”。 - 可能是粗体。然后你可以继续解释The only setting that really matters is the linker's /subsystem option [...] and using v120_xp changes this setting 你实际上的意思是“你不会有麻烦”。这对我来说并不简单。可能是我的错。无论如何,感谢您的时间和解释,答案已接受。
    • 使用v14x_xp 工具集的关键原因是在include/lib 路径中有Windows 7.1A SDK。它不使用特殊的编译器,只使用最后一个支持面向 Windows XP 的 Windows SDK。 Windows 8.0 SDK 或更高版本不支持面向 Windows XP。当然,您可以让标头的某些部分正常工作,但您很容易得到一个在 XP 上实际上不支持的 API。最后一点,VS 2019 (16.7) 是最后一个支持 Windows XP 的 Visual C++ CRT 版本。
    猜你喜欢
    • 2014-09-30
    • 2013-11-17
    • 2015-12-09
    • 1970-01-01
    • 2019-07-14
    • 1970-01-01
    • 2014-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多