vs2010编译器配置
(2011-12-26 23:02:16)
标签:
it |
分类: postgraduate |
相信很多人对这个错误是一点也不陌生,甚至有些害怕,我也一样。其实自己遇到过这样的问题,也每次都解决了这样的问题,但关键是自己没总结,所以总是再遇到再改,很烦人,查资料也麻烦。现在有时间了总结下。
遇到问题我最喜欢F1,所以还是先看MSDN是怎么说的:
To fix by checking the following possible causes
1.
2.
3.
4.
5.
·
·
·
6.
7.
其中1,我一直说学习托管编程,但只是打雷。其实使用托管就是不使用C++的编译器,而是编译成
中间语言,这样可以充分利用.Net的庞大的类库,不熟悉不说,以后学习了可以补上。
其实遇到这个错误并不可怕,只要我们找出原因,知道为什么会引起这些错误后,就不难解决。根据自己平时的心得和MSDN的解释,主要有下面这些情况,可能引起lnk 2005错误。
A、 全局变量的重复定义,在实际的编程中我们应该尽量不使用全局变量。她会产生如下的错误:
AAA.obj error LNK2005 int book c?book@@3HA already defined in BBB.obj
其实这个错误很好找,book@@3HA这个就是你重复定义了的变量。至于是怎么重复定义,情况
很多。关键是要理解清楚变量的声明和定义,以及extern关键字的使用,这些是基础知识。
B、 文件的重复包含,因为头文件中会有很多的变量,函数声明,所以要是被重复无次序包含的话,就有可能产生lnk 2005错误。
解决方法是使用#ifndef #define #endif宏来预防头文件被多次包含时重复编译。或者使用#pragma once做预编译。
C、 库版本包含错误,这个里面分两种情况说下。
1、 第三方库引起错误,这个在做directshow程序的时候记忆尤为深刻。现在自己把那个库分别编译成了strmbasd.lib、strmbasd_Unicode.lib、strmbase.lib、strmbase_Unicode.lib,这样根据不同的版本和字符编码链接不同的库,就不会出现错误。这样问题没什么好多,自己注意就是。
2、 关于编译器编译选项设置引起的lnk 2005错误。如:
1>MSVCRTD.lib(MSVCR80D.dll) : error LNK2005: __vsnwprintf_s already defined in LIBCMTD.lib(vswprnc.obj)
1>MSVCRTD.lib(MSVCR80D.dll) : error LNK2005: __vsnprintf_s already defined in LIBCMTD.lib(vsnprnc.obj)
1>MSVCRTD.lib(ti_inst.obj) : error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) already defined in LIBCMTD.lib(typinfo.obj)
1>MSVCRTD.lib(ti_inst.obj) : error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" (??4type_info@@AAEAAV0@ABV0@@Z) already defined in LIBCMTD.lib(typinfo.obj)
为编译选项选错而链接了错误的版本。关于编译选项所对应的链接库,可以参考msdn以下连接:
C Run-Time Libraries (CRT)
C run-time library |
Associated DLL |
Characteristics |
Option |
Preprocessor directives |
libcmt.lib |
None,static |
Multithreaded, static link |
_MT |
|
msvcrt.lib |
msvcr90.dll |
Multithreaded, dynamic link (import library for MSVCR90.DLL). Be aware that if you use the Standard C++ Library, your program will need MSVCP90.DLL to run. |
_MT, _DLL |
|
libcmtd.lib |
None,static |
Multithreaded, static link (debug) |
/MTd |
_DEBUG,_MT |
msvcrtd.lib |
msvcr90d.dll |
Multithreaded, dynamic link (import library for MSVCR90D.DLL) (debug). |
/MDd |
_DEBUG,_MT, |
msvcmrt.lib |
msvcm90.dll |
C Runtime import library. Used for mixed managed/native code. |
/clr |
|
msvcurt.lib |
msvcm90.dll |
CRuntime |
/clr:pure |
|
Standard C++ Library
Standard C++ Library |
Characteristics |
Option |
Preprocessor directives |
LIBCPMT.LIB |
Multithreaded, static link |
/MT |
_MT |
MSVCPRT.LIB |
Multithreaded, dynamic link (import library for MSVCP90.dll) |
/MD |
_MT, _DLL |
LIBCPMTD.LIB |
Multithreaded, static link |
/MTd |
_DEBUG, _MT |
MSVCPRTD.LIB |
Multithreaded, dynamic
link |
/MDd |
_DEBUG, _MT, _DLL |
根据给出的信息,以及上面两个表的分析。
我们配置的是/MTd。也即是多线程的DLL的Debug版本,当设置编译器选项为/MTd的时候,编译器
会将库名 LIBCMTD.lib放入.obj文件中,以便链接器使用 LIBCMTD.lib 解析外部符号。所以要将MSVCRTD.lib这个库去掉,方法如下图:
D、error LNK2005: _DllMain@12 already defined in XXX.obj
处理方
当 C 运行时 (CRT) 库和 Microsoft 基础类 (MFC) 库的链接顺序有误时,可能会出现以下
LNK2005 错误之一:
mfcs40d.lib(dllmodul.obj):error LNK2005:_DllMain@12 already defined
in
MSVCRTD.LIB (dllmain.obj)
mfcs42d.lib(dllmodul.obj):error LNK2005:_DllMain@12 already defined
in
msvcrtd.lib(dllmain.obj)
CRT 库对 new、delete 和 DllMain 函数使用弱外部链接。MFC 库也包含 new、delete 和
DllMain 函数。这些函数要求先链接 MFC 库,然后再链接 CRT 库。 所以按顺序修改即可