學習VC++時常常會遇到連接錯誤LNK2001,該錯誤很是討厭,由於對於編程者來講,最好改的錯誤莫過於編譯錯誤,而通常說來發生鏈接錯誤時,編譯都已經過。產生鏈接錯誤的緣由很是多,尤爲LNK2001錯誤,經常令人不明其因此然。若是不深刻地學習和理解VC++,要想改正鏈接錯誤LNK2001很是困難。編程
初學者在學習VC++的過程當中,遇到的LNK2001錯誤的錯誤消息主要爲:windows
unresolved external symbol 「symbol」(不肯定的外部「符號」)。多線程
若是鏈接程序不能在全部的庫和目標文件內找到所引用的函數、變量或標籤,將產生此錯誤消息。通常來講,發生錯誤的緣由有兩個:一是所引用的函數、變量不存在、拼寫不正確或者使用錯誤;其次可能使用了不一樣版本的鏈接庫。併發
如下是可能產生LNK2001錯誤的緣由:函數
一.因爲編碼錯誤致使的LNK2001性能
1.不相匹配的程序代碼或模塊定義(.DEF)文件能致使LNK2001。例如, 若是在C++源文件內聲明瞭一變量「var1」,卻試圖在另外一文件內以變量「VAR1」訪問該變量,將發生該錯誤。學習
2.若是使用的內聯函數是在.CPP文件內定義的,而不是在頭文件內定義將致使LNK2001錯誤。編碼
3.調用函數時若是所用的參數類型同函數聲明時的類型不符將會產生LNK2001。線程
4.試圖從基類的構造函數或析構函數中調用虛擬函數時將會致使LNK2001。debug
5.要注意函數和變量的可公用性,只有全局變量、函數是可公用的。靜態函數和靜態變量具備相同的使用範圍限制。當試圖從文件外部訪問任何沒有在該文件內聲明的靜態變量時將致使編譯錯誤或LNK2001。
函數內聲明的變量(局部變量) 只能在該函數的範圍內使用。
C++ 的全局常量只有靜態鏈接性能。這不一樣於C,若是試圖在C++的多個文件內使用全局變量也會產生LNK2001錯誤。一種解決的方法是須要時在頭文件中加入該常量的初始化代碼,並在.CPP文件中包含該頭文件;另外一種方法是使用時給該變量賦以常數。
二.因爲編譯和連接的設置而形成的LNK2001
1.若是編譯時使用的是/NOD(/NODEFAULTLIB)選項,程序所須要的運行庫和MFC庫在鏈接時由編譯器寫入目標文件模塊, 但除非在文件中明確包含這些庫名,不然這些庫不會被連接進工程文件。在這種狀況下使用/NOD將致使錯誤LNK2001。
2.若是沒有爲wWinMainCRTStartup設定程序入口,在使用Unicode和MFC時將獲得「unresolved external on _WinMain@16」的LNK2001錯誤信息。
3.使用/MD選項編譯時,既然全部的運行庫都被保留在動態連接庫以內,源文件中對「func」的引用,在目標文件裏即對「__imp__func」 的引用。若是試圖使用靜態庫LIBC.LIB或LIBCMT.LIB進行鏈接,將在__imp__func上發生LNK2001;若是不使用/MD選項編
譯,在使用MSVCxx.LIB鏈接時也會發生LNK2001。
4.使用/ML選項編譯時,如用LIBCMT.LIB連接會在_errno上發生LNK2001。
5.當編譯調試版的應用程序時,若是採用發行版模態庫進行鏈接也會產生LNK2001;一樣,使用調試版模態庫鏈接發行版應用程序時也會產生相同的問題。
6.不一樣版本的庫和編譯器的混合使用也能產生問題,由於新版的庫裏可能包含早先的版本沒有的符號和說明。
編程時打開了函數內聯(/Ob1或/Ob2),可是在描述該函數的相應頭文件裏卻關閉了函數內聯(沒有inline關鍵字),這時將獲得該錯誤信息。爲避免該問題的發生,應該在相應的頭文件中用inline關鍵字標誌內聯函數。
8.不正確的/SUBSYSTEM或/ENTRY設置也能致使LNK2001。
解決方法:
解決外部符號錯誤:_main,_WinMain@16,__beginthreadex
在建立MFC項目時, 不使用MFC AppWizard嚮導, 就會在編譯時產生不少鏈接錯誤, 如error LNK2001錯誤, 典型的錯誤提示有:
libcmtd.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@
msvcrtd.lib(crtexew.obj) : error LNK2001: unresolved external symbol _WinMain@
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex
1. Windows子系統設置錯誤, 提示:
libcmtd.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
Windows項目要使用Windows子系統, 而不是Console, 能夠這樣設置:
[Project] --> [Settings] --> 選擇"Link"屬性頁, 在Project Options中將/subsystem:console改爲/subsystem:windows
2. Console子系統設置錯誤, 提示:
LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@控制檯項目要使用Console子系統, 而不是Windows, 設置:
[Project] --> [Settings] --> 選擇"Link"屬性頁
3. 程序入口設置錯誤, 提示:
msvcrtd.lib(crtexew.obj) : error LNK2001: unresolved external symbol _WinMain@一般, MFC項目的程序入口函數是WinMain, 若是編譯項目的Unicode版本, 程序入口必須改成wWinMainCRTStartup, 因此須要從新設置程序入口:
[Project] --> [Settings] --> 選擇"Link"屬性頁, 在Category中選擇Output, 再在Entry-point symbol中填入wWinMainCRTStartup, 便可
4. 線程運行時庫設置錯誤, 提示:nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex這是由於MFC要使用多線程時庫, 須要更改設置:
[Project] --> [Settings] --> 選擇"C/C++"屬性頁, 在Category中選擇Code Generation,再在Use run-time library中選擇Debug Multithreaded或者multithreaded
其中, Single-Threaded 單線程靜態連接庫(release版本)
Multithreaded 多線程靜態連接庫(release版本)
multithreaded DLL 多線程動態連接庫(release版本)
Debug Single-Threaded 單線程靜態連接庫(debug版本)
Debug Multithreaded 多線程靜態連接庫(debug版本) )
Debug Multithreaded DLL 多線程動態連接庫(debug版本)
單線程: 不須要多線程調用時, 多用在DOS環境下
多線程: 能夠併發運行
靜態庫: 直接將庫與程序Link, 能夠脫離MFC庫運行
動態庫: 須要相應的DLL動態庫, 程序才能運行
release版本: 正式發佈時使用
debug版本: 調試階段使用