小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

你所不知道的C和C++運(yùn)行庫(kù)

 king9413 2014-05-10

         你所不知道的C和C++運(yùn)行庫(kù)

   周五晚,小雨,少見(jiàn)的未加班。無(wú)聊,遂準(zhǔn)備寫(xiě)一篇博客,介紹一下C和C++運(yùn)行庫(kù),只因發(fā)現(xiàn)工作幾年的人對(duì)此一知半解的大有人在。
  
  在使用VC構(gòu)建項(xiàng)目時(shí),經(jīng)常會(huì)遇到下面的鏈接錯(cuò)誤:

                   


  初學(xué)者面對(duì)這些錯(cuò)誤常常不知所錯(cuò):libcmt.lib是什么東西?msvcrtd.dll又是干嗎用的?在使用VC++時(shí)我們也常常對(duì)下面的運(yùn)行庫(kù)配置項(xiàng)感到疑惑,它們到底究竟是什么意思呢?甚至一些工作了很多年的程序員也對(duì)此一知半解。今天讓我們來(lái)了解一下它們。
    

從C和C++運(yùn)行庫(kù)說(shuō)起

  為了提高C語(yǔ)言的開(kāi)發(fā)效率,C標(biāo)準(zhǔn)定義了一系列常用的函數(shù),稱(chēng)為C庫(kù)函數(shù)。C標(biāo)準(zhǔn)僅僅定義了函數(shù)原型,并沒(méi)有提供實(shí)現(xiàn)。因此這個(gè)任務(wù)留給了各個(gè)支持C語(yǔ)言標(biāo)準(zhǔn)的編譯器。每個(gè)編譯器通常實(shí)現(xiàn)了標(biāo)準(zhǔn)C的超集,稱(chēng)為C運(yùn)行時(shí)庫(kù)(C Run Time Libray) ,簡(jiǎn)稱(chēng)CRT。對(duì)于VC++編譯器來(lái)說(shuō),它提供的CRT庫(kù)支持C標(biāo)準(zhǔn)定義的標(biāo)準(zhǔn)C函數(shù),同時(shí)也有一些專(zhuān)門(mén)針對(duì)windows系統(tǒng)特別設(shè)計(jì)的函數(shù)。
  與C語(yǔ)言類(lèi)似,C++也定義了自己的標(biāo)準(zhǔn),同時(shí)提供相關(guān)支持庫(kù),我們把它稱(chēng)為C++運(yùn)行時(shí)庫(kù)或C++標(biāo)準(zhǔn)庫(kù)。
  由于C++對(duì)C的兼容性,C++標(biāo)準(zhǔn)庫(kù)包括了C標(biāo)準(zhǔn)庫(kù),除此之外還包括IO流和標(biāo)準(zhǔn)模板庫(kù)STL。

VC++在何處實(shí)現(xiàn)C和C++運(yùn)行庫(kù)

  VC++完美的支持C和C++標(biāo)準(zhǔn),因此也就按照C和C++的標(biāo)準(zhǔn)定義的函數(shù)原型實(shí)現(xiàn)了上述運(yùn)行時(shí)庫(kù)。為了方便有不同需求的客戶(hù)的使用,VC++分別實(shí)現(xiàn)了動(dòng)態(tài)鏈接庫(kù)DLL版本和靜態(tài)庫(kù)LIB版本。同時(shí)為了支持程序調(diào)試且不影響程序的性能,又分別提供了對(duì)應(yīng)的調(diào)試版本。調(diào)試版本的名稱(chēng)在Release版本名稱(chēng)后添了字母d。

  對(duì)于C運(yùn)行時(shí)庫(kù)CRT,VC6.0、VC2005、VC2008和VC2010均提供了DLL版本和LIB版本。上述各個(gè)編譯器提供的LIB版的CRT庫(kù),均實(shí)現(xiàn)在libcmt.lib。對(duì)應(yīng)的調(diào)試版名稱(chēng)為libcmtd.lib。

  而DLL版本名稱(chēng)根據(jù)編譯器不同而不同,我們可以從名稱(chēng)上加以分辨。
  VC6.使用的CRT庫(kù)的DLL版本在MSVCRT.DLL中實(shí)現(xiàn), 對(duì)應(yīng)調(diào)試版本為MSVCRTD.LIB。
  VC2005使用的CRT庫(kù)的DLL版本在MSVCR80.DLL中實(shí)現(xiàn),對(duì)應(yīng)調(diào)試版本為MSVCR80.DLL。
  VC2008使用的CRT庫(kù)的DLL版本在MSVCR90.DLL中實(shí)現(xiàn),對(duì)應(yīng)調(diào)試版本為MSVCR90D.DLL。
  VC2010使用的CRT庫(kù)的DLL版本在MSVCR100.DLL中實(shí)現(xiàn),對(duì)應(yīng)調(diào)試版本為MSVCR100D.DLL。

  C++標(biāo)準(zhǔn)兼容C標(biāo)準(zhǔn),但VC各版本將C++編譯器使用的C標(biāo)準(zhǔn)庫(kù)與C編譯器使用的C運(yùn)行庫(kù)一起實(shí)現(xiàn),它們使用相同的運(yùn)行庫(kù)。

  對(duì)于C++標(biāo)準(zhǔn)庫(kù)中的IO流和STL,VC6.0、VC2005、VC2008和VC2010也提供了DLL版本和LIB版本。
  LIB版均實(shí)現(xiàn)在libcpmt.lib中,對(duì)應(yīng)的調(diào)試版本為libcpmtd.lib。

  不同版本的編譯器實(shí)現(xiàn)的DLL也不相同。
  VC6.使用的C++類(lèi)庫(kù)的 DLL版本在MSVCP60.DLL中實(shí)現(xiàn), 對(duì)應(yīng)調(diào)試版本為MSVCP60D.LIB。
  VC2005使用的C++類(lèi)庫(kù)的DLL版本在MSVCP80.DLL中實(shí)現(xiàn),對(duì)應(yīng)調(diào)試版本為MSVCP80.DLL。
  VC2008使用的C++類(lèi)庫(kù)的 DLL版本在MSVCP90.DLL中實(shí)現(xiàn),對(duì)應(yīng)調(diào)試版本為MSVCP90D.DLL。
  VC2010使用的C++類(lèi)庫(kù)的DLL版本在MSVCP100.DLL中實(shí)現(xiàn),對(duì)應(yīng)調(diào)試版本為MSVCP100D.DLL。

  在各個(gè)版本的編譯器中,我們可以通過(guò)配置選項(xiàng)來(lái)設(shè)置程序使用的C和C++運(yùn)行時(shí)庫(kù)的類(lèi)型。如下圖(其他版本編譯器大同小異):
  
   
  MT選項(xiàng):鏈接LIB版的C和C++運(yùn)行庫(kù)。在鏈接時(shí)就會(huì)在將C和C++運(yùn)行時(shí)庫(kù)集成到程序中成為程序中的代碼,程序體積會(huì)變大。
  MTd選項(xiàng):LIB的調(diào)試版。
  MD選項(xiàng):使用DLL版的C和C++運(yùn)行庫(kù),這樣在程序運(yùn)行時(shí)會(huì)動(dòng)態(tài)的加載對(duì)應(yīng)的DLL,程序體積會(huì)減小,缺點(diǎn)是在系統(tǒng)沒(méi)有對(duì)應(yīng)DLL時(shí)程序無(wú)法運(yùn)行。
  MDd選項(xiàng):表示使用DLL的調(diào)試版。
  在《由使用LeakDialog時(shí)遇到的問(wèn)題而引出的一些分析》這篇文章中的實(shí)驗(yàn)一,使用VC6.0的默認(rèn)配置沒(méi)有攔截到內(nèi)存泄露。其原因是VC6.0的控制臺(tái)項(xiàng)目默認(rèn)配置是靜態(tài)鏈接CRT庫(kù)(單線程版,后面會(huì)介紹)。

動(dòng)態(tài)版(DLL)和靜態(tài)版(LIB)C和C++運(yùn)行庫(kù)的優(yōu)缺點(diǎn)

  因?yàn)殪o態(tài)版必須把C和C++運(yùn)行庫(kù)復(fù)制到目標(biāo)程序中,所以產(chǎn)生的可執(zhí)行文件會(huì)比較大。同時(shí)對(duì)于使用多個(gè)模塊的大型軟件來(lái)說(shuō),如果每個(gè)模塊均選擇靜態(tài)鏈接C或C++運(yùn)行庫(kù),在程序運(yùn)行時(shí)就會(huì)存在多個(gè)運(yùn)行庫(kù)。在鏈接時(shí)也會(huì)出現(xiàn)重復(fù)定義的問(wèn)題,如文章首第一張圖所示。
  使用DLL版的C和C++運(yùn)行庫(kù),程序在運(yùn)行時(shí)動(dòng)態(tài)的加載對(duì)應(yīng)的DLL。程序體積變小,但一個(gè)很大的問(wèn)題就是一旦找不到對(duì)應(yīng)DLL,程序?qū)o(wú)法運(yùn)行。假設(shè)使用VC6.0并選擇使用MD選項(xiàng)構(gòu)建,那么當(dāng)用戶(hù)使用VC2005來(lái)使用這個(gè)DLL時(shí)很可能出現(xiàn)找不到MSVCRT.DLL或MSVCP60.DLL的情況。

  在這里介紹一個(gè)很好的工具:Dependency Walker,可以用來(lái)分析DLL的依賴(lài)關(guān)系,同時(shí)查看DLL導(dǎo)出的函數(shù),使用方法請(qǐng)Google。
  使用該工具打開(kāi)MSVCRT.DLL,如下圖:
   
  我們可以在其中找到我們經(jīng)常使用使用的C函數(shù),如printf ,getchar,malloc等。
  打開(kāi)MSVCP100.DLL,也可以找到這些C函數(shù):

    
  在開(kāi)發(fā)的過(guò)程中我們也會(huì)遇到如下圖的鏈接錯(cuò)誤,LIBCD.lib究竟是何方神圣呢?

                         
  它其實(shí)是LIBC.lib的調(diào)試版,而LIBC.lib是只有在VC6.0才會(huì)使用的靜態(tài)庫(kù),該庫(kù)是CRT的單線程版,用于支持單線程版本的CRT。VC2005等更高版本的編譯器已經(jīng)不再提供單線程版本,轉(zhuǎn)而使用多線程版的MSVCR80.DLL或libcmt.lib。

  當(dāng)遇到上述符號(hào)定義沖突的鏈接錯(cuò)誤時(shí),可以選擇忽略libcd.lib。

2014.2.28 于浙江杭州

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多