我正在使用包含四组本机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)
我有以下要求:
我想要做的是使用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库。
答案 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函数做了这个,只有更多。增加涉及对线程和区域设置的支持。