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

C++ C++;链接器问题,是否有解决这些问题的通用方法?,c++,visual-c++,linker,C++,Visual C++,Linker,我对链接过程几乎一无所知,当我试图开始一个新项目或添加一个新库时,它几乎总是会阻碍我。每当我搜索这些类型错误的修复时,我都会发现有类似问题的人,但很少有任何修复 有没有什么通用的方法来找出问题所在并加以解决 我正在使用VisualStudio2010,并且静态地将我的库链接到我的程序中。我的问题似乎总是源于与LIBCMT(D).lib、MSVCRT(D).lib和其他一些双重定义某些函数的库的冲突。如果它是重要的,我的意图是避免使用“托管”C++。 如果您的错误与LIbCMT(d).LIB等相关

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

有没有什么通用的方法来找出问题所在并加以解决


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

如果您的错误与LIbCMT(d).LIB等相关,通常这取决于您链接到使用与您不同的CRT版本的库的事实。唯一真正的修复方法是使用为您使用的CRT的同一版本编译的库(通常也有“调试”和“发布”版本),或者(如果您不顾一切)更改您使用的CRT版本以匹配库中的一个


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

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

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

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

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


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

对某些内容几乎一无所知,并要求提供一个新的版本这是一种解决问题的方法……很明显,预防是最好的药物。了解它的工作原理,这样你就可以使用最佳实践,预防错误,并解决问题。好的,就看一本入门书。关于它,我想说很多可恨的事情。比如链接器在今天这个时代不应该存在。但我会把它塞进我的博客里s、 我至少理解了这个概念以及他们现在应该做什么……这就是事实。我已经将我的一个库设置为静态链接到STD库,而不是使用共享库。因此,libcmt提供了所有多个定义的内容。谢谢!@Clairvoire:这是静态库的一个常见问题。这就是为什么当您必须安装例如Boost时,您必须为每个可用的CRT生成静态库(并且在VC++2003中,有单线程静态、多线程静态和多线程dll的所有调试/发布组合),这非常不方便。