我可以将使用v120_xp工具集构建的静态库链接到使用VS2013中的v120工具集构建的EXE / DLL吗?

时间:2014-02-26 12:55:58

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

我正在使用包含四组本机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. 由set C 中的项目生成的那些DLL和EXE必须在Windows XP和Windows 7上运行;
  2. 由集合D中的项目生成的那些DLL和EXE,另一方面, 不需要在Windows XP上运行
  3. 我想要做的是使用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库。

1 个答案:

答案 0 :(得分:9)

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

这真的很直接,如果你想让可执行文件在XP上运行,那么使用v120_xp工具集是一项艰难的要求。如果你不这样做并不重要。 真正重要的唯一设置是链接器/子系统选项。从VS2012开始,工具集设置此项,以便您的可执行文件包含6.0作为所需的子系统。从Vista开始的Windows一代。并使用v120_xp更改此设置,使用4.0的旧版值。从NT 4.0开始的一代。 XP是第5.0代,它将拒绝运行子系统设置为6.0的程序

确实在某种程度上,操作系统会查看它并决定打开哪个appcompat垫片。将子系统设置为标题中的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函数做了这个,只有更多。增加涉及对线程和区域设置的支持。