1. 現(xiàn)象: 在MFC項(xiàng)目中使用 boost 庫的時(shí)候,,出現(xiàn)了很多鏈接錯(cuò)誤(如下)。其中 MFC項(xiàng)目 的配置是: 錯(cuò)誤: ①:msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: char const * __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::c_str(void)const " (?c_str@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEPBDXZ) 已經(jīng)在 async_server.obj 中定義 ②:MSVCRTD.lib(MSVCR90D.dll) : error LNK2005: __CrtDbgReportW 已經(jīng)在 libcmtd.lib(dbgrptw.obj) 中定義 等等,,大概有接近200個(gè)類似錯(cuò)誤,。 2. 分析 msvcprtd.lib(靜態(tài)) LIBCMTD.lib(動(dòng)態(tài)) 我們?cè)诰幾gC程序時(shí),通常要鏈接 CRT(c run-time library),。CRT可分為動(dòng)態(tài)庫和靜態(tài)庫,,動(dòng)態(tài)庫有兩個(gè):LIBCMTD.lib(debug版)和LIBCMT.lib(release版);靜態(tài)庫有兩個(gè):MSVCRTD.lib(debug)和MSVCRT.lib(release),。 而MSVC項(xiàng)目對(duì)應(yīng)為: 多執(zhí)行線程調(diào)試(/MTD):LIBCMTD.lib 多執(zhí)行線程(/MT):LIBCMT.lib 多執(zhí)行線程調(diào)試DLL(/MDd):MSVCRTD.lib 多執(zhí)行線程DLL(/MD):MSVCRT.lib 請(qǐng)注意,,以上只是單純 C 語言的程序庫而沒有包含 C++ 語言在內(nèi)。如果你的程序系統(tǒng)中,,有包含 C++ 語言的程序代碼的話,,那又是另外一回事了。但是在項(xiàng)目屬性的頁面中,,為什么找不到相關(guān)的設(shè)定選項(xiàng)呢,?因?yàn)?MSVC 悄悄地幫程序設(shè)計(jì)者代勞處理掉了。只要在程序代碼中使用 #include 語法納入任何一個(gè) C++ 的標(biāo)頭文件,例如 iostream 或 fstream,,MSVC 就會(huì)在鏈接器的運(yùn)作階段中,,自動(dòng)幫我們鏈接 C++ 的執(zhí)行階段程序庫。而 C++ 的執(zhí)行階段程序庫,,同樣可分為四個(gè)版本: 靜態(tài)鏈接:LIBCPMTD.lib(Debug版本)LIBCPMT.lib 動(dòng)態(tài)鏈接:MSVCPRTD.lib(Debug版本):執(zhí)行文件相依于 MSVCP90D.dll 至于程序執(zhí)行文件使用的是靜態(tài)鏈接或者動(dòng)態(tài)鏈接的版本,,就仰賴于 C 語言的版本設(shè)定選項(xiàng)了。舉個(gè)例子來說,,如果你撰寫了一個(gè) Debug 組態(tài)的 C++ 程序,,并且保留項(xiàng)目原先預(yù)設(shè)的生成選項(xiàng)(動(dòng)態(tài)鏈接),那么最終生成出來的程序執(zhí)行文件將會(huì)相依于 MSVCR90D.dll 以及 MSVCP90D.dll 兩個(gè) DLL 文件,。如果將相同的程序以 Release 組態(tài)生成完成,,則會(huì)相依于MSVCR90.dll 以及 MSVCP90.dll 二者。 出現(xiàn)這些是因?yàn)槌绦蛲瑫r(shí)鏈接了 LIBCMTD.lib與MSVCRTD.lib而造成函數(shù)定義版本沖突,。也就是說,,程序鏈接器已經(jīng)在其中一個(gè) CRT的版本中找到所需的函數(shù)定義,但此時(shí)卻又跳出另外一位 CRT,,也給了一份相同函數(shù)的實(shí)現(xiàn)版本,,所以鏈接器無法判斷應(yīng)該忽略誰并且選擇誰。而這個(gè)狀況的發(fā)生原因,,就是你的程序與程序所鏈接的外部程序庫,,使用了不同的 CRT版本之故。當(dāng)時(shí)我在編譯 boost 庫的時(shí)候選擇的選項(xiàng)中有 “l(fā)ink=static runtime-link=shared” ,,所以生成的 lib 文件使用的是動(dòng)態(tài)的 CRT ,,而在上面的圖中可以看到我的 MFC 項(xiàng)目中使用的是靜態(tài)的CRT。所以出現(xiàn)沖突,。 3. 解決辦法 方法一:重新編譯 boost 庫,,采用 runtime-link=static 來編譯。也就是說,,你使用的第三方庫必須編譯時(shí)使用的是靜態(tài)運(yùn)行時(shí)庫。 方法二:將上面的 “MFC的使用” 選項(xiàng)改為“在共享 DLL 中使用 MFC”,。(不推薦,,可能還有其他庫錯(cuò)誤) 注:如果我們想寫一個(gè)dll庫,選擇“多執(zhí)行線程調(diào)試DLL(/MDd)”,,那么我們應(yīng)該使用 runtime-link=shared 編譯的靜態(tài)boost庫,。 |
|