几年前,我发现了一个 hack,它允许您强制 Visual C++ 链接具有特定优先级的库。这并不优雅,但很实用。
似乎 Visual C++ 的链接器会根据符号依赖关系动态生成链接顺序。通过预先添加符号引用,您可以强制链接器包含链接器输入中指定的第一个库。 请注意,我只使用 Visual C++ 6 和 8 (2005) 对此进行了测试。
例如,假设您有两个带有 XML_ParserCreate 符号的库:
- libexpat.lib - XML_ParserCreate
- someother.lib - OtherSymbolsYouNeed, XML_ParserCreate
首先,按照您的预期排序您的库依赖项,libexpat.lib,然后是 someother.lib。通过命令行,这些将是link.exe 的选项。在 Visual Studio 2005 中,它们是项目的配置属性 -> 链接器 -> 输入 -> 附加依赖项 下的选项。我想 Visual C++ 2010 也有类似的菜单。
接下来,使用/INCLUDE 链接器选项添加一个命令行选项,该选项预先定义已知的重复符号。在 Visual Studio 2005 中,可以在项目的 Configuration Properties -> Linker -> Command Line -> Additional options 下添加:
/out some.exe ... libexpat.lib someother.lib
/include:XML_ParserCreate
此符号的定义将导致链接器立即选择终止(实现)它的第一个库。一般来说,Visual C++ 会产生重复符号的错误;如果您还没有指定,请确保您还指定了 /FORCE:MULTIPLE 链接器选项。
我对此的具体需求是使用DUMA 内存调试库。它定义了多种内存函数,这些函数也在 libcmtd.lib 中定义。以下将错误地链接 libcmtd 的 _malloc 版本,尽管库顺序似乎相反:
/out some.exe ... duma.lib libcmtd.lib
/FORCE:MULTIPLE
这是通过手动添加符号解决的,并且多年来一直可靠运行:
/out some.exe ... duma.lib libcmtd.lib
/INCLUDE:_malloc /FORCE:MULTIPLE