链接错误:已经在*****中定义了xxx.LIB ::究竟出了什么问题?

时间:2010-04-27 23:18:50

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

问题:

我正在尝试使用名为DCMTK的库,该库使用了一些其他外部库(zlib,libtiff,libpng,libxml2,libiconv)。我从同一个网站下载了这些外部库(* .LIB& * .h文件)。现在,当我编译DCMTK库时,我收到链接错误(793错误),如下所示:

Error   2   error LNK2005: __encode_pointer already defined in MSVCRTD.lib(MSVCR90D.dll)    LIBCMTD.lib dcmmkdir 
Error   3   error LNK2005: __decode_pointer already defined in MSVCRTD.lib(MSVCR90D.dll)    LIBCMTD.lib dcmmkdir 
Error   4   error LNK2005: __CrtSetCheckCount already defined in MSVCRTD.lib(MSVCR90D.dll)  LIBCMTD.lib dcmmkdir 
Error   5   error LNK2005: __invoke_watson already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir 
Error   6   error LNK2005: __errno already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir 
Error   7   error LNK2005: __configthreadlocale already defined in MSVCRTD.lib(MSVCR90D.dll)    LIBCMTD.lib dcmmkdir 
Error   8   error LNK2005: _exit already defined in MSVCRTD.lib(MSVCR90D.dll)   LIBCMTD.lib dcmmkdir 

文档

这似乎是这个库的一个流行错误,因此,他们确实有一个FAQ条目来解决这个问题,(http://forum.dcmtk.org/viewtopic.php?t=35)说:

  
      
  • 问题是链接器试图将组合起来,   Visual的不兼容版本   C ++运行时库成单   二进制文件。
  •   
  • 如果不是项目的所有部分和您的库,就会发生这种情况   链接反对是生成的   Visual中相同的代码生成选项   C ++。
  •   
  • 不要使用/ NODEFAULTLIB解决方法,因为奇怪的软件   可能会发生崩溃。解决问题!

  •   
  • DCMTK默认使用“Multithreaded”或“Multithreaded”编译   调试“代码生成选项(   后者用于调试模式)。

  •   
  • 更改所有代码的项目设置以使用这些代码   生成选项,
  •   
  • 或更改所有DCMTK模块的代码生成并重新编译。
  •   
  • MFC用户要注意:DCMTK应该使用“多线程DLL”或   “多线程DLL调试”设置如果   你想将库链接到一个   MFC申请。
  •   

解决其他问题:

Huge Amount of Linker Issues with Release Build Only说:

  

您的发布版似乎是   试图链接到那些东西   内置调试。你可能有一个   破坏了你的构建中的依赖,(或   你错过了重建的东西   如果您的项目是手动释放   通常建在一块)。

     

从技术上讲,你似乎是   用不同的方式建立项目   C Run Time library个设置,一个   与“多线程”,另一个   “多线程调试”。调整   所有项目的设置   使用相同的味道   图书馆和问题应该消失

问题:

到目前为止,我曾经认为Name mangling是唯一可能导致链接失败的问题,如果没有标准化的话。刚才我知道还有其他事情可能导致同样的效果。

  1. 怎么了“调试模式”(多线程调试)和“释放模式”(多线程)?什么完全正在引擎盖下发生?为什么完全这件事导致链接错误?

  2. 我想知道是否有一种叫做“单线程调试”和“单线程调试”的东西也会导致同样的事情。

  3. 文档讲述了“代码生成选项”。什么代码生成选项?他们是谁?

  4. 文档特别警告我们不要使用/ NODEFAULTLIB解决方法。 (示例/ NODEFAULTLIB:msvcrt)。为什么?我怎么会引起麻烦?到底是什么?

  5. 请解释MFC用户文档中的最后一点。因为我将在本项目的后期使用MFC。解释我们为什么要这样做?如果我不这样做会带来什么麻烦。
  6. 还有什么你想提的吗?我的意思是类似的错误。我对Linker&amp ;;非常感兴趣它的问题。所以,如果有类似的东西,你可以提及它们或至少一些关键词。

3 个答案:

答案 0 :(得分:8)

  

怎么了“调试模式”   (多线程调试)和“发布   模式“(多线程)?究竟是什么   引擎盖下发生了什么?为什么   这件事确实引起了联系   错误?

由于几个不同的原因,链接器拖入库中。最简单的是,链接器命令行或链接器命令行上的链接器应答文件中列出了库。但是,无论是在项目中编译还是打包到库中,任何目标文件都可以包含linker options,包括请求特定库。实际上,Visual C ++编译器会自动嵌入与您使用的项目选项相匹配的链接器选项编译时。

在链接时,所有目标文件和静态库文件中的对象的所有链接器选项都会合并在一起。如果请求了多个CRT库文件名,链接器将读入所有这些文件名,并且它们会出现命名冲突,其中链接器不知道要使用哪个。

  

我想知道是否有所谓的东西   “单线程调试”和   “单线程”再次引起   同样的事情。

过去常见,但Visual C ++的最后几个版本只提供了多线程兼容的库。

  

文档谈论了一些事情   “代码生成选项”。什么代码   生成选项?他们是谁?

inside your project options

  

文档特别警告我们   不要使用/ NODEFAULTLIB解决方法。   (示例/ NODEFAULTLIB:msvcrt)。为什么?   我怎么会引起麻烦?什么   究竟是什么?

如果使用/ NODEFAULTLIB,则会忽略存储在目标文件和库中对象中的所有链接器设置。您最终将没有运行时库,也许会遗漏其他库。你可以手工添加它们,但它仍然是一个大混乱。

  

请解释一下最后一点   MFC用户的文档。因为   我将在稍后使用MFC   项目。解释我们为什么要这样做?   如果我有什么麻烦   别。还有更多你想要的东西   提到?我的意思是类似的   错误。我对Linker非常感兴趣   &安培;它的问题。所以,如果有的话   类似的东西你可以提到它们   或至少一些关键词。

MFC应用程序和MFC库必须使用相同的内存管理功能,以便MFC分配的内存可以被应用程序释放,反之亦然。 FILE句柄和其他资源也是共享的。 MFC DLL已经编译为在DLL中使用CRT,并且为了能够共享资源,您需要使用相同的CRT,这也意味着使用DLL。

答案 1 :(得分:0)

答案 2 :(得分:0)

您需要配置项目属性,以便您的调试构建链接DCMTK的调试版本以及您的版本构建链接与DCMTK的版本构建。

以上是您需要做的。以下是您询问的其他一些随机事物的解释。

除了多线程库(发布和调试版本)之外,旧版本的Visual Studio曾经拥有单线程库(发布和调试版本)。对于您的项目,您可以假装从未存在单线程库。

如果您尝试使用随机方法欺骗链接器关闭并让客户而不是自己发现问题,您可能会发现/ NODEFAULTLIB选项会这样做。 DCMTK库的制作者警告你不要这样做,因为其他人过去做过同样愚蠢的事情。