對于一個靜态連結庫L.lib,它的使用者app.exe會靜态連結L.lib,意思是app.exe會将L.lib中的代碼(app需要的部分,例如函數定義,類的定義等等)連結到app.exe中.
而對于L.lib本身來說,它的CRT(C Run-Time Libraries)有多種配置,這裡僅考慮/MTd.如果配置為/MTd,L.lib會連結靜态庫libcmtd.lib,這意味着會将libcmtd.lib中的代碼(L.lib需要的部分,例如函數定義,類的定義等等)連結到L.lib中.為了更清楚說明問題,下面舉一個例子.
L.lib中有檔案L.h和L.cpp,L.h的内容(部分)如下:
#param once
#include <string>
void testfun();
L.cpp中的内容(部分)如下:
std::basic_string<char> g_teststring("aaaaaaaaaa");
vod testfun(){
//使用了标準靜态庫libcmtd.lib中的類,會将std::basic_string<char>定義代碼複制到該子產品中.
std::basic_string<char> str(g_teststr);
}
Build之後生成L.lib,然後以二進制方式打開L.obj,可以看到如下内容:
...std::basic_string<char,std::char_traits<char>,std::allocator<char> >...
很明顯,L.obj包含有std::basic_string<char>的定義,這才是靜态連結的含義.那麼這會有什麼問題呢?
現在假設一種情況,E.exe的CRT配置為/MDd,這意味着它會動态連結msvcrtd.lib,同時E.exe也連結到L.lib,假如該工程中有一個檔案E.CPP,它的内容如下:
#include "L.h"
testfun();//來自于L.lib的頭檔案L.h
std::string<char> g_teststdstring("bbbbbbbbbb"); //A
Build該工程,就會發生LINK2005的錯誤:
msvcprtd.lib(MSVCP90D.dll): error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void)" (??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ) already defined in L.lib(L.obj)
這個錯誤很明顯指出,std::basic_string<char>重複定義,這是因為E.cpp在同時使用了L.lib和msvcrtd.lib,編譯完成後,E.obj會連結L.lib和msvcrtd.lib時,此時發現在這兩個庫中都有std::basic_string<char>的定義,這顯然是不允許的.
如果将E.cpp中的A行代碼改為:
std::string<TCHAR> g_teststdstring(_T("bbbbbbbb"));
就不會有連結錯誤LINK2005了.
需要注意的是,如果E.cpp中出現關于vector的變量的定義,同樣會出現LINK2005連結錯誤,即使你沒有使用std::basic_string.這說明隻要你在工程E.exe中同時使用了動态标準連結庫和靜态連結标準庫,就有可能出現标準庫中某些類型重複定義的錯誤.
現在你應該徹底了解了LIN2005的錯誤了,問題的根源已經找到,解決辦法自己應該能想到了吧.
本文轉自jetyi51CTO部落格,原文連結:http://blog.51cto.com/jetyi/785974 ,如需轉載請自行聯系原作者