方案一、
編程中經(jīng)常能遇到LNK2005錯(cuò)誤——重復(fù)定義錯(cuò)誤,其實(shí)LNK2005錯(cuò)誤并不是一個(gè)很難解決的錯(cuò)誤。弄清楚它形成的原因,就可以輕松解決它了。
造成LNK2005錯(cuò)誤主要有以下幾種情況:
1.重復(fù)定義全局變量??赡艽嬖趦煞N情況:
A、對(duì)于一些初學(xué)編程的程序員,有時(shí)候會(huì)以為需要使用全局變量的地方就可以使用定義申明一下。其實(shí)這是錯(cuò)誤的,全局變量是針對(duì)整個(gè)工程的。正確的應(yīng)該是在一個(gè)CPP文件中定義如下:int? g_Test;那么在使用的CPP文件中就應(yīng)該使用:extern? int? g_Test即可,如果還是使用int? g_Test,那么就會(huì)產(chǎn)生LNK2005錯(cuò)誤,一般錯(cuò)誤錯(cuò)誤信息類似:AAA.obj? error? LNK2005? int? book? c?book@@3HA? already? defined? in? BBB.obj。切記的就是不能給變量賦值否則還是會(huì)有LNK2005錯(cuò)誤。
這里需要的是“聲明”,不是“定義”!根據(jù)C++標(biāo)準(zhǔn)的規(guī)定,一個(gè)變量是聲明,必須同時(shí)滿足兩個(gè)條件,否則就是定義:
(1)聲明必須使用extern關(guān)鍵字;(2)不能給變量賦初值
所以,下面的是聲明:
extern? int? a;
下面的是定義
int? a;? int? a? =? 0;? extern? int? a? =0;
B、對(duì)于那么編程不是那么嚴(yán)謹(jǐn)?shù)某绦騿T,總是在需要使用變量的文件中隨意定義一個(gè)全局變量,并且對(duì)于變量名也不予考慮,這也往往容易造成變量名重復(fù),而造成LNK2005錯(cuò)誤。
2.頭文件的包含重復(fù)。往往需要包含的頭文件中含有變量、函數(shù)、類的定義,在其它使用的地方又不得不多次包含之,如果頭文件中沒有相關(guān)的宏等防止重復(fù)鏈接的措施,那么就會(huì)產(chǎn)生LNK2005錯(cuò)誤。解決辦法是在需要包含的頭文件中做類似的處理:#ifndef? MY_H_FILE? ? ? //如果沒有定義這個(gè)宏
#define? MY_H_FILE? ? ? //定義這個(gè)宏
…….? ? ? //頭文件主體內(nèi)容
…….
#endif
上面是使用宏來做的,也可以使用預(yù)編譯來做,在頭文件中加入:
#pragma? once
//頭文件主體
3.使用第三方的庫造成的。這種情況主要是C運(yùn)行期函數(shù)庫和MFC的庫沖突造成的。具體的辦法就是將那個(gè)提示出錯(cuò)的庫放到另外一個(gè)庫的前面。另外選擇不同的C 函數(shù)庫,可能會(huì)引起這個(gè)錯(cuò)誤。微軟和C有兩種C運(yùn)行期函數(shù)庫,一種是普通的函數(shù)庫:LIBC.LIB,不支持多線程。另外一種是支持多線程的: msvcrt.lib。如果一個(gè)工程里,這兩種函數(shù)庫混合使用,可能會(huì)引起這個(gè)錯(cuò)誤,一般情況下它需要MFC的庫先于C運(yùn)行期函數(shù)庫被鏈接,因此建議使用支持多線程的msvcrt.lib。所以在使用第三方的庫之前首先要知道它鏈接的是什么庫,否則就可能造成LNK2005錯(cuò)誤。如果不得不使用第三方的庫,可以嘗試按下面所說的方法修改,但不能保證一定能解決問題,前兩種方法是微軟提供的:
A、選擇VC菜單Project->Settings->Link->Catagory選擇Input,再在Ignore? libraries? 的Edit欄中填入你需要忽略的庫,如:Nafxcwd.lib;Libcmtd.lib。然后在Object/library? Modules的Edit欄中填入正確的庫的順序,這里需要你能確定什么是正確的順序,呵呵,God? bless? you!
B、選擇VC菜單Project->Settings->Link頁,然后在Project? Options的Edit欄中輸入/verbose:lib,這樣就可以在編譯鏈接程序過程中在輸出窗口看到鏈接的順序了。
C、選擇VC菜單Project->Settings->C/C++頁,Catagory選擇Code? Generation后再在User? Runtime? libraray中選擇MultiThread? DLL等其他庫,逐一嘗試。
關(guān)于編譯器的相關(guān)處理過程,參考:
http://www.donews.net/xzwenlan/archive/2004/12/23/211668.aspx
這就是我所遇到過的LNK2005錯(cuò)誤的幾種情況,肯定還有其他的情況也可能造成這種錯(cuò)誤,所以我不希望你在看完這篇文章以后,再遇到LNK2005錯(cuò)誤時(shí)候,不動(dòng)腦筋的想對(duì)號(hào)入座的排除錯(cuò)誤。編程的過程就是一個(gè)思考的過程,所以還是多多開動(dòng)你的頭腦,那樣收獲會(huì)更多!
方案二、
LNK2005...already defined...ERROR
鏈接時(shí)出錯(cuò)提示:
LIBCMT.lib(crt0dat.obj) : error LNK2005: __amsg_exit already defined in MSVCRTD.lib(MSVCR80D.dll)
LIBCMT.lib(crt0dat.obj) : error LNK2005: __initterm_e already defined in MSVCRTD.lib(MSVCR80D.dll)
LIBCMT.lib(crt0dat.obj) : error LNK2005: _exit already defined in MSVCRTD.lib(MSVCR80D.dll)
LIBCMT.lib(crt0dat.obj) : error LNK2005: __exit already defined in MSVCRTD.lib(MSVCR80D.dll)
LIBCMT.lib(crt0dat.obj) : error LNK2005: __cexit already defined in MSVCRTD.lib(MSVCR80D.dll)
LIBCMT.lib(fflush.obj) : error LNK2005: _fflush already defined in MSVCRTD.lib(MSVCR80D.dll)
LIBCMT.lib(setlocal.obj) : error LNK2005: __configthreadlocale already defined in MSVCRTD.lib(MSVCR80D.dll)
LIBCMT.lib(tidtable.obj) : error LNK2005: __encode_pointer already defined in MSVCRTD.lib(MSVCR80D.dll)
LIBCMT.lib(tidtable.obj) : error LNK2005: __decode_pointer already defined in MSVCRTD.lib(MSVCR80D.dll)
LIBCMT.lib(invarg.obj) : error LNK2005: __invoke_watson already defined in MSVCRTD.lib(MSVCR80D.dll)
LIBCMT.lib(realloc.obj) : error LNK2005: _realloc already defined in MSVCRTD.lib(MSVCR80D.dll)
LIBCMT.lib(crt0init.obj) : error LNK2005: ___xi_a already defined in MSVCRTD.lib(cinitexe.obj)
LIBCMT.lib(crt0init.obj) : error LNK2005: ___xi_z already defined in MSVCRTD.lib(cinitexe.obj)
LIBCMT.lib(crt0init.obj) : error LNK2005: ___xc_a already defined in MSVCRTD.lib(cinitexe.obj)
LIBCMT.lib(crt0init.obj) : error LNK2005: ___xc_z already defined in MSVCRTD.lib(cinitexe.obj)
LIBCMT.lib(hooks.obj) : error LNK2005: "void __cdecl terminate(void)" (?terminate@@YAXXZ) already defined in MSVCRTD.lib(MSVCR80D.dll)
LIBCMT.lib(winxfltr.obj) : error LNK2005: __XcptFilter already defined in MSVCRTD.lib(MSVCR80D.dll)
LIBCMT.lib(mlock.obj) : error LNK2005: __unlock already defined in MSVCRTD.lib(MSVCR80D.dll)
LIBCMT.lib(mlock.obj) : error LNK2005: __lock already defined in MSVCRTD.lib(MSVCR80D.dll)
LIBCMT.lib(dosmap.obj) : error LNK2005: __errno already
?