Linker Tools Error LNK2001 报错
鏈接器工具錯誤LNK2001
未解析的外部符號“符號”
如果代碼引用鏈接器在其搜索的所有庫和對象文件中找不到的內容(如函數、變量或標簽),則會生成此錯誤消息。一般來說,出現錯誤的原因有兩個:代碼所要求的不存在(例如,符號拼寫錯誤或使用錯誤的情況),或者代碼要求錯誤的東西(您使用的是混合版本的庫)。一些來自產品的一個版本,另一些來自另一個版本)。
各種編碼和構建錯誤都會導致LNK2001。下面列出了幾個具體的原因,其中一些原因鏈接到更詳細的解釋。
編碼問題
代碼或模塊定義(.DEF)文件中的大小寫不匹配可能會導致LNK2001。例如,如果在一個C++源文件中命名一個變量“VAR1”,并試圖在另一個C++源文件中訪問它為“VAR1”,則會收到此錯誤。解決方法是完全匹配所有引用中符號的大小寫。
使用函數內聯但在.CPP文件而不是頭文件中定義函數的項目可能會導致LNK2001。
如果您使用C++,請確保在從C++程序調用C函數時使用Extn“C”。通過使用外部“C”,可以強制使用C命名約定。注意像/TP或/TC這樣的編譯器開關,無論文件擴展名是什么,都會強制將文件編譯成C(/TC)或C++(/TP)文件,或者您可能得到不同于您期望的函數名。
試圖引用沒有外部鏈接的函數或數據會導致LNK2001。在C++中,內聯函數和const數據具有內部鏈接,除非顯式指定為Extn。
缺少函數體或變量將導致LNK2001。只有一個函數原型或外部聲明將允許編譯器無誤地繼續,但鏈接器將無法解析對地址的調用或對變量的引用,因為沒有保留函數代碼或變量空間。
Name decoration將函數的參數合并到最終的修飾函數名中。調用參數類型與函數聲明中的參數類型不匹配的函數可能會導致LNK2001。
錯誤包含的原型將導致編譯器期望未提供的函數體。如果同時具有函數F的類和非類實現,請謹防C++范圍解析規則。
在使用C++時,請確保包含類的特定函數的實現,而不只是類定義中的原型。
試圖從抽象基類的構造函數或析構函數調用純虛擬函數將導致LNK2001,因為根據定義,純虛擬函數沒有基類實現。
只有全局函數和變量是公共的。
通過定義使用靜態修飾符聲明的函數具有文件作用域。靜態變量有相同的限制。試圖從聲明靜態變量的文件外部訪問它們可能會導致編譯錯誤或LNK2001。
函數中聲明的變量(局部變量)只能在該函數的范圍內使用。
C++全局常量具有靜態鏈接。這與C不同。如果在多個文件中使用C++中的全局常量,則會得到錯誤LNK2001。另一種方法是在頭文件中包含const初始化,并在必要時在.CPP文件中包含該頭,就像它是一個函數原型一樣。另一種方法是使變量為非常量,并在評估時使用常量引用。
編譯和鏈接問題
鏈接時所需的Microsoft運行時庫和MFC庫的名稱由Microsoft編譯器包含在對象文件模塊中。如果使用/NOD(/NODEFAULTLIB)選項,則除非已顯式包含這些庫,否則這些庫將不會鏈接到項目中。在這種情況下,使用/NOD將導致錯誤LNK2001。
如果使用Unicode和MFC,如果不創建wWinMainCRTStartup的入口點,則在@16上會得到一個未解析的外部。使用/ENTRY選項或在“項目設置”對話框中鍵入此值。(若要在開發環境中找到此選項,請單擊“項目”菜單上的“設置”,然后單擊“鏈接”選項卡,然后單擊“類別”框中的“輸出”。)請參見Unicode編程摘要。
有關詳細信息,請參閱聯機信息系統中的以下知識庫文章。訪問文章的一個簡單方法是復制上面的“Q”編號,從“幫助”菜單打開“搜索”對話框,選擇“查詢”選項卡,然后將該編號粘貼到第一個文本框中并按回車鍵。
Q125750“PRB:錯誤LNK2001:’\u WinMain@16’:未解析的外部符號”
Q131204“PRB:錯誤的項目選擇導致LNK2001在WinMain@16上”
Q100639“Microsoft基礎類庫中的Unicode支持”
鏈接
Q100639“Microsoft基礎類庫中的Unicode支持”
將使用/MT編譯的代碼與LIBC.LIB庫鏈接會導致LNK2001位于_beginthread、_beginthreadex、_endthread和_endthreadex上。
使用/MD編譯時,源代碼中對“func”的引用將成為對象中的引用“imp”func,因為所有運行時現在都保存在一個DLL中。如果嘗試與靜態庫LIBC.LIB或LIBCMT.LIB鏈接,則會在’uuu imp_uufunc上獲得LNK2001。如果在不使用/MD編譯時嘗試與MSVCxx.LIB鏈接,則不一定總能得到LNK2001,但很可能會遇到其他問題。
將用顯式或隱式/ML編譯的代碼鏈接到LIBCMT.LIB會導致LNK2001出現錯誤。
在生成應用程序的調試版本時與發布模式庫鏈接可能會導致LNK2001。類似地,使用/Mxd選項(/MLd、/MTd或/MDd)和/或定義“調試”,然后與發布庫鏈接,將為您提供潛在的未解決外部問題(以及其他問題)。將發布模式生成與調試庫鏈接也會導致類似的問題。
混合版本的微軟庫和編譯器產品可能是有問題的。新編譯器版本的庫可能包含以前版本中包含的庫中找不到的新符號。使用DUMPBIN查找符號是否在32位對象文件或庫中。
目前在編譯器供應商之間或者甚至在編譯器的不同版本之間沒有C++命名的標準。因此,鏈接與其他編譯器編譯的對象文件可能不會產生相同的命名方案,從而導致錯誤LNK2001。
在不同模塊上混合內聯和非內聯編譯選項會導致LNK2001。如果一個C++庫是通過函數內聯打開(/OB1或/OB2)創建的,但是對應于函數描述的頭文件已經內聯關閉(沒有內聯關鍵字),那么您將得到這個錯誤。為了防止出現此問題,請在要包含在其他文件中的頭文件中使用inline定義內聯函數。
如果使用的是#pragma inline_depth編譯器指令,請確保設置的值為2或更大,并確保使用的是/Ob1或/Ob2編譯器選項。
在創建僅資源DLL時省略LINK選項/NOENTRY將導致LNK2001。
使用不正確的/SUBSYSTEM或/ENTRY設置可能會導致LNK2001。例如,如果您編寫一個基于字符的應用程序(控制臺應用程序)并指定/SUBSYSTEM:WINDOWS,您將得到一個未解析的WinMain外部。有關這些選項和入口點的更多信息,請參閱/SUBSYSTEM和/entry linker選項。
出口問題
將應用程序從16位移植到32位時,可能會發生LNK2001。當前的32位模塊定義(.DEF)文件語法要求在“導出”部分中列出不帶下劃線(未修飾)的“cdecl”、“stdcall”和“fastcall”函數。這與16位語法不同,后者必須用下劃線(修飾)列出。有關詳細信息,請參閱模塊定義文件的“導出”部分的說明。
任何在.DEF文件中列出但未找到的導出都將導致LNK2001。這可能是因為它不存在,拼寫不正確,或者使用修飾名(.DEF文件不采用修飾名)。
此錯誤消息后面跟著致命錯誤LNK1120。
以下各節提供了有關上述列表中指定的某些問題的更詳細信息。
缺少函數體或變量
姓名裝飾
符號不公開
自動(函數范圍)變量
C++中的全局常量
函數內聯問題
總結
以上是生活随笔為你收集整理的Linker Tools Error LNK2001 报错的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 杂七杂八的记录
- 下一篇: oledb32.dll的作用