国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
你所不知道的C和C++運行庫

         你所不知道的C和C++運行庫

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

                   



  初學者面對這些錯誤常常不知所錯:libcmt.lib是什么東西?msvcrtd.dll又是干嗎用的?在使用VC++時我們也常常對下面的運行庫配置項感到疑惑,它們到底究竟是什么意思呢?甚至一些工作了很多年的程序員也對此一知半解。今天讓我們來了解一下它們。
    


從C和C++運行庫說起

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

VC++在何處實現(xiàn)C和C++運行庫

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

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

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

  C++標準兼容C標準,但VC各版本將C++編譯器使用的C標準庫與C編譯器使用的C運行庫一起實現(xiàn),它們使用相同的運行庫。

  對于C++標準庫中的IO流和STL,VC6.0、VC2005、VC2008和VC2010也提供了DLL版本和LIB版本。
  LIB版均實現(xiàn)在libcpmt.lib中,對應的調(diào)試版本為libcpmtd.lib。

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

  在各個版本的編譯器中,我們可以通過配置選項來設(shè)置程序使用的C和C++運行時庫的類型。如下圖(其他版本編譯器大同小異):
  
   

  MT選項:鏈接LIB版的C和C++運行庫。在鏈接時就會在將C和C++運行時庫集成到程序中成為程序中的代碼,程序體積會變大。
  MTd選項:LIB的調(diào)試版。
  MD選項:使用DLL版的C和C++運行庫,這樣在程序運行時會動態(tài)的加載對應的DLL,程序體積會減小,缺點是在系統(tǒng)沒有對應DLL時程序無法運行。
  MDd選項:表示使用DLL的調(diào)試版。
  在《由使用LeakDialog時遇到的問題而引出的一些分析》這篇文章中的實驗一,使用VC6.0的默認配置沒有攔截到內(nèi)存泄露。其原因是VC6.0的控制臺項目默認配置是靜態(tài)鏈接CRT庫(單線程版,后面會介紹)。

動態(tài)版(DLL)和靜態(tài)版(LIB)C和C++運行庫的優(yōu)缺點

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

  在這里介紹一個很好的工具:Dependency Walker,可以用來分析DLL的依賴關(guān)系,同時查看DLL導出的函數(shù),使用方法請Google。
  使用該工具打開MSVCRT.DLL,如下圖:
   

  我們可以在其中找到我們經(jīng)常使用使用的C函數(shù),如printf ,getchar,malloc等。
  打開MSVCP100.DLL,也可以找到這些C函數(shù):

    

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

                         

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

  當遇到上述符號定義沖突的鏈接錯誤時,可以選擇忽略libcd.lib。

2014.2.28 于浙江杭州

本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
帶你玩轉(zhuǎn)Visual Studio
VS中的 MD/MT設(shè)置
MSVC與CRT的恩怨情仇 >> 猴子靈藥 [Monkey Potion]
丟失msvcp140.dll怎么辦
OpenGL常用的庫
缺少DLL文件的用戶來這里下載
更多類似文章 >>
生活服務
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服