代码改变世界

Error hnk2005:exist already defined in msvcrt.lib(MSVCR100.dll)_LIBCMTD.lib 解决方案

2013-01-23 21:33  chenkai  阅读(9970)  评论(0编辑  收藏  举报

今天在调试发布一个Windows 8游戏版本时发现这个异常:

Error    1 : error LNK2005: _exit already defined in msvcrt.lib(MSVCR100.dll)    LIBCMTD.lib    SampleGame

刚开始在开发Debug时并没有出现过这样问题.当尝试发布一个新版本.构建Realse 包时.于是乎就超过75个 Lnk2005 Error出现List中:

2013-01-23_152751

 

ok.这样瞬间就爆发了75个基本类同的错误.首先看了MS官方对这个错误定义:Linker Tools Error LNK2005.可见LNK在C++编程时常见的.一个重复定义的错误.那么总结一下官方针对这个Error定义出现的三种情况如下:

A:头文件重复包含.

在头文件中常常包含具有变量 函数 和类定义的. 但是问题是如果头文件在相关宏等相关的重复链接处理措施.就会到时重复引用.

B:重复定义全局变量

这个应该就不用多说了.全局变量时针对整个工程的 .正确做法应该在一个Cpp文件中定义.类似:

   1:  int test_datatag

那么使用调用的方法就应该为:

   1:  extern int test_datatag

如果还继续使用test_datatag则会立即爆出异常:

ObjError LNK2005 in index.cpp test_datatag already defined in index.obj

C:引用第三方库.

这种情况比较普遍.主要是因为C Run time 函数库和MFC库存在冲突照成的.在目前的VC对C Runtime 运行时库总共有6种:

Single-threaded (libc.lib) libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib
Multithreaded (libcmt.lib) libc.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib
Multithreaded using DLL (msvcrt.lib) libc.lib, libcmt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib
Debug Single-threaded (libcd.lib) libc.lib, libcmt.lib, msvcrt.lib, libcmtd.lib, msvcrtd.lib
Debug Multithreaded (libcmtd.lib) libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, msvcrtd.lib
Debug Multithreaded using DLL (msvcrtd.lib) libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib

如果我们项目中引用不同的C函数库. 微软针对C有两种C函数库.一种是普通的函数库:LIBC.LIB.格式/.特点是不支持多线程.另外一种是支持多线程的MSVCRT.lib.如果在一个工程中混合使用这两种函数库.则很容易导致LNK2005错误.一般情况下不推荐混合使用.如果真的有实际需求.最好处理方式采用MFC先C run time函数库link链接.因此推荐使用支持多线程的msvcrt.lib.

C run time 运行时函数包如下库:

2013-01-23_205728

当引用第三方库时很容易出现这种错误.例如boot和WXWindow使用MD来编译.也就是上面提到支持多线程的C runtime 函数库.这时如果我们编辑自己项目没有指明/MD 来编译.就会导致两种C函数出现冲突.并且在编译时导致大量的LNK2005错误.

来看一下关于C run time 函数库编译形式常用如下:

2013-01-23_205842

说到这大概明白项目在Realse时大批量出现Error LNK2005原因.也就是因为引用库导致的.现在看看目前项目中C/C++编译设置: 打开项目在Properties->C/C++->All Options中找到Runtime Libraty值

2013-01-23_210230

可见为MD.

so.说了这么多搞清楚问题所在.如果Fix这个问题.

根据官方对着这个问题提出解决方案如下:

首先打开项目Properties->Configuration Properties->Linker中如果我们引用会看到对应的库会看到对应的值:

2013-01-23_210833

这个问题是因为两个库之间存在冲突引起,.的.可以发现冲突出现LIBCMD.lib中.官方给出做法也相当的简单直接.可以再项目直接忽略对该函数库的引用:可以Ignore Specific Libraies设置对应的值:

2013-01-23_211159

设置保存后.重写Rebuild 项目.发现所有错误全部没有了.只是存在一定警告.,编译完全通过.当然这种方式虽然简单但显得比较粗暴.因为libcmtd 这个库有时候不能忽略,忽略后会有不能解析的外部符号错误.会导致有些运行时Run time 异常抛出.整个应用程序crash掉.

当然这种方式依然无法排除另外一种情况.

当C运行时[CRT]库和MS基础类MFC库链接、顺序有误是.同样也会导致LNK2005错误.主要是因为CRT库对new、Delete、DllMain函数使用弱外部链接方式.MFC库也包含了new、Delete、DllMain函数定义.这些函数要求先链接MFC库然后再链接CRT库.

完整解决方式采用强制链接器做法按照正确顺序链接.通过在Properties-Configuration Properties->Linker->Command Line设置参数: /FORCE:MULTIPLE -关于该操作操作请参考官方文档 Force Multiple

2013-01-23_212412

其实问题关键在于两遍引用库在进行编译时设置必须相同才能REalse正常引用.当然相对更简单的方式.逐个对引用项目进行对应Md编译.然后重新添加Linker链接关系.这种方法虽然耗时但解决问题最为直接.也算是比较快捷方式之一.

设置完成发现项目正常编译通过.

参考资料:

C Run Time  Libraries

/MD, /ML, /MT, /LD (Use Run-Time Library)

error LNK2005: _exit already defined in msvcrt.lib(MSVCR90.dll)_LIBCMTD.lib_

error LNK2005: xxx already defined in MSVCRT.lib(MSVCR100.dll) C:\something\LIBCMT.lib(setlocal.obj)

无觅相关文章插件,快速提升流量