【问题标题】:C++ Linker issues, is there a generalized way to troubleshoot these?C ++链接器问题,是否有解决这些问题的通用方法?
【发布时间】:2011-12-26 20:38:48
【问题描述】:

我对链接过程几乎一无所知,当我尝试开始一个新项目或添加一个新库时,它几乎总是会妨碍我。每当我搜索此类错误的修复程序时,我都会找到遇到类似问题但很少有任何修复程序的人。

是否有任何通用的方法可以找出问题所在并加以解决?

我正在使用 Visual Studio 2010,并将我的库静态链接到我的程序中。我的问题似乎总是源于与 LIBCMT(D).lib、MSVCRT(D).lib 和其他一些双重定义某些函数的库的冲突。如果这很重要,我的意图是避免使用“托管”C++。

【问题讨论】:

  • 对某事几乎一无所知,并寻求一种通用的故障排除方法……显然,最好的药物是预防。了解它的工作原理,以便您可以使用最佳做法、防止错误并对其进行故障排除。
  • 好的,只需阅读入门读物即可。关于它,我想说很多可恨的话。就像在这个时代不应该存在链接器一样。但我猜我会填的。不过,我至少了解这个概念以及他们现在应该做什么。

标签: c++ visual-c++ linker


【解决方案1】:

如果您的错误与 LIBCMT(D).lib 等有关,通常这取决于您链接的库使用的 CRT 版本与您的不同。唯一真正的解决方法是使用为您使用的 CRT 的相同版本编译的库(通常也有“调试”和“发布”版本也是出于这个原因),或者(如果你很绝望)更改 CRT 版本你用来匹配库之一。

幕后发生的事情是您的程序和库都需要 CRT 函数才能正常工作,并且每个函数都已经链接到它。如果它们链接到它的相同版本,则不会发生任何不好的事情(链接器看到它是相同的并且不会抱怨),否则相同功能的多个实现冲突,因此链接器不知道哪个是正确的哪些对象模块(而且,由于它们可能不兼容二进制,两个 CRT 的内部数据结构将不兼容)。

【讨论】:

  • 原来就是这样。我已将我的一个库设置为静态链接到 STD 库,而不是使用共享库。因此所有来自 libcmt 的多个定义的东西。谢谢!
  • @Clairvoire:这是静态库的常见问题。这就是为什么当你必须安装例如Boost,您必须为每个可用的 CRT 生成静态库(并且在 VC++ 2003 中,有单线程静态、多线程静态、多线程 dll 的所有调试/发布组合),这非常不方便。
【解决方案2】:

您提到的特定链接错误(使用 LIBCMT(D).lib、MSVCRT(D).lib 库)与程序中模块/库之间的代码生成选项冲突有关。

当您编译模块时,编译器会自动在生成的 .obj 中插入一些对运行时库 (LIBCMT&MSVCRT) 的引用。现在,每种代码生成模式都有这些库的一个版本(我指的是配置属性 -> C/C++ -> 代码生成 -> 运行时库中的选项)。因此,如果您有两个使用不同模式编译的模块,它们中的每一个都将引用不同版本的库,链接器将尝试包含两者,当然会有重复的符号,因为基本上所有符号都是相同的在这些库中,只有它们的实现不同。

解决方案分为三个部分。首先,确保一个项目中的所有模块都使用相同的模式。其次,如果项目之间存在依赖关系,则它们都必须使用相同的模式。第三,如果您使用第三方库,您必须要么知道他们使用哪种模式(并采用它),要么能够以所需的模式重新编译它们。

最后一个是最难的。有时,库是预编译的,并不总是提供者提供有关所使用模式的信息。更糟糕的是,如果您使用多个第三方库,它们可能会有冲突的模式。在这些情况下,您没有比反复试验更好的选择。

另请注意,每个 Visual Studio 版本都有自己的一组运行时库,因此在使用第三方库时,您必须使用使用与您正在使用的相同版本的 Visual Studio 编译的库。如果提供者不提供,你唯一的选择就是自己重新编译。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-30
    • 1970-01-01
    • 1970-01-01
    • 2011-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多