C ++链接器问题,是否有一种通用的方法来解决这些问题?

时间:2011-12-26 20:38:48

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

我对链接过程几乎一无所知,当我尝试启动新项目或添加新库时,它几乎总会受到阻碍。每当我搜索这些类型错误的修复程序时,我会发现有类似问题但很少有任何修复的人。

是否有任何通用的方法来找到问题所在并修复它?

我正在使用visual studio 2010,并将我的库静态链接到我的程序中。我的问题似乎总是源于与LIBCMT(D).lib,MSVCRT(D).lib以及其他一些双重定义某些函数的库的冲突。如果它很重要,我的意图是避免使用" managed" C ++。

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

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

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

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

最后一个是最困难的。有时,库是预编译的,并不总是提供程序提供有关所用模式的信息。更糟糕的是,如果您使用多个第三方库,则可能存在冲突模式。在这些情况下,你没有比试错更好的选择。

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