無法解析的外部符號解決方法彙總
一、使用lib庫
靜態連結庫和動態連結庫都需要使用.lib檔案。對於靜態連結庫來說,.lib檔案包含了函式的說明和定義;而對於動態連結庫來說,.lib檔案只有函式的說明,執行時還需要.dll檔案。那麼如何使用.lib檔案呢?有三種方法:
第一種方法:首先,在Visual Studio中"專案->屬性->聯結器->常規->附加庫目錄"寫上.lib庫所在資料夾;其次,"專案->屬性->聯結器->輸入->附加依賴項"中寫上.lib庫的名稱。
第二種方法:在.h或.cpp檔案中用編譯預處理指令#pragma comment(lib, "XXX.lib");
第三種方法:Visual Studio中,例如,你的解決方案裡A,B兩個工程,B工程生成.lib庫共A工程用,那麼就右鍵A工程"引用->通用屬性->框架和引用->新增新引用"選擇B工程即可。
二、無法解析的外部符號問題
出現這個問題,不用懷疑,一定是你沒有包含lib庫,或者沒有正確包含lib庫。何謂沒有正確包含?32位的專案不能使用64位的lib,反之亦然;有時候Debug模式下生產的lib也不能共Release模式使用,反之亦然。
高階玩家看:
當然我剛才說的出現“無法解析的外部符號”就是沒有正確包含lib庫仍有些片面,例如,Visual Studio的一個解決方案有A、B兩個工程,B生成dll供A使用,A正確包含了B的dll和lib,可是有時候還是會出現B總定義的函式“無法解析的外部符號”問題。這個原因可能為:B既然是要生成dll共A使用,那麼B中的函式和類以及全域性變數都要申明為__declspec(dllexport);而A中也需要申明這些函式(或類或全域性變數)為__declspec(dllimport)。以類為例,加入B中定義類TestB那麼TestB.h應該這樣:
<pre name="code" class="cpp">//TestB.h
#ifdefine PROJECT_B
#define DLL __declspec(dllexport)
#else
#define DLL __declspec(dllimport)
#endif
class DLL TestB{
//....
};
專案B中在"屬性->C++->前處理器->前處理器定義"中定義PROJECT_B,這樣,專案B就申明類TestB為__declspec(dllexprot);而專案A包含了標頭檔案TestB.h,但是沒有定義前處理器巨集PROJECT_B,則申明TestB為__declspec(dllimport)。
三、visual studio 詭異bug
沒有使用其他lib庫,只是一個.cpp檔案使用另一個.cpp檔案裡定義的類函式,結果一直報“無法解析的外部符號錯誤”。 最後重新新增.h檔案.cpp檔案,把出問題的.h檔案.cpp檔案從專案中移除,並拷貝到新的.h和.cpp檔案裡,才解決。 2017-5-2 23:49:16 更新“三、visual studio 詭異bug” ---------------------------------------------- 四、行內函數也可能導致“無法解析的外部符號”錯誤 今天重用別人的程式碼,總有幾個“無法解析的外部符號”錯誤解決不了,函式都是有定義的。最後發現,只要把函式定義前的inline去掉就好了。 2017-7-4 23:05:40 更新 ----------------------------------------------五、其它
我做工程時學到的自認為比較有用的東西:
1.Visual Studio的“查詢和替換”以及“在檔案中查詢”功能,只能查詢解決方案檢視下的檔案,如果你的.h檔案沒有包含進專案(即使其它的.h或.cpp檔案包含了這個.h),那麼就不會被搜尋到。
2.有時候引用附加庫的編譯預處理指令#pragma comment(lib, "XXX.lib")會放在標頭檔案裡,正如1.所說,如果包含#pragma的.h檔案沒有新增進專案,就不會被搜尋到。這時候,你可能覺得奇怪,明明需要使用B.lib,可是A工程的專案配置裡又沒有引用。原因就在這。我也是被這個問題困擾了一下午,才終於搞明白。
3.搜尋功能要學會使用正則表示式,例如我要搜尋#pragma comment這個指令,但不知道#pragma和comment之間有幾個空格,怎麼辦?pragma.*comment就行了。