你所不知道的C和C 執行庫

2021-07-30 10:33:09 字數 3193 閱讀 2719

**:

你所不知道的c和c++執行庫

周五晚,小雨,少見的未加班。無聊,遂準備寫一篇部落格,介紹一下c和c++執行庫,只因發現工作幾年的人對此一知半解的大有人在。

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

從c和c++執行庫說起

為了提高c語言的開發效率,c標準定義了一系列常用的函式,稱為c庫函式。c標準僅僅定義了函式原型,並沒有提供實現。因此這個任務留給了各個支援c語言標準的編譯器。每個編譯器通常實現了標準c的超集,稱為c執行時庫(c run time libray) ,簡稱crt。對於vc++編譯器來說,它提供的crt庫支援c標準定義的標準c函式,同時也有一些專門針對windows系統特別設計的函式。

與c語言類似,c++也定義了自己的標準,同時提供相關支援庫,我們把它稱為c++執行時庫或c++標準庫。

由於c++對c的相容性,c++標準庫包括了c標準庫,除此之外還包括io流和標準模板庫stl。

vc++在何處實現c和c++執行庫

vc++完美的支援c和c++標準,因此也就按照c和c++的標準定義的函式原型實現了上述執行時庫。為了方便有不同需求的客戶的使用,vc++分別實現了動態鏈結庫dll版本和靜態庫lib版本。同時為了支援程式除錯且不影響程式的效能,又分別提供了對應的除錯版本。除錯版本的名稱在release版本名稱後添了字母d。

對於c執行時庫crt,vc6.0、vc2005、vc2008和vc2010均提供了dll版本和lib版本。上述各個編譯器提供的lib版的crt庫,均實現在libcmt.lib。對應的除錯版名稱為libcmtd.lib。

而dll版本名稱根據編譯器不同而不同,我們可以從名稱上加以分辨。

vc6.使用的crt庫的dll版本在msvcrt.dll中實現, 對應除錯版本為msvcrtd.lib。

vc2005使用的crt庫的dll版本在msvcr80.dll中實現,對應除錯版本為msvcr80.dll。

vc2008使用的crt庫的dll版本在msvcr90.dll中實現,對應除錯版本為msvcr90d.dll。

vc2010使用的crt庫的dll版本在msvcr100.dll中實現,對應除錯版本為msvcr100d.dll。

c++標準相容c標準,但vc各版本將c++編譯器使用的c標準庫與c編譯器使用的c執行庫一起實現,它們使用相同的執行庫。

對於c++標準庫中的io流和stl,vc6.0、vc2005、vc2008和vc2010也提供了dll版本和lib版本。

lib版均實現在libcpmt.lib中,對應的除錯版本為libcpmtd.lib。

不同版本的編譯器實現的dll也不相同。

vc6.使用的c++類庫的 dll版本在msvcp60.dll中實現, 對應除錯版本為msvcp60d.lib。

vc2005使用的c++類庫的dll版本在msvcp80.dll中實現,對應除錯版本為msvcp80.dll。

vc2008使用的c++類庫的 dll版本在msvcp90.dll中實現,對應除錯版本為msvcp90d.dll。

vc2010使用的c++類庫的dll版本在msvcp100.dll中實現,對應除錯版本為msvcp100d.dll。

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

mt選項:鏈結lib版的c和c++執行庫。在鏈結時就會在將c和c++執行時庫整合到程式中成為程式中的**,程式體積會變大。

mtd選項:lib的除錯版。

md選項:使用dll版的c和c++執行庫,這樣在程式執行時會動態的載入對應的dll,程式體積會減小,缺點是在系統沒有對應dll時程式無法執行。

mdd選項:表示使用dll的除錯版。

在《由使用leakdialog時遇到的問題而引出的一些分析》

這篇文章中的實驗一,使用vc6.0的預設配置沒有攔截到記憶體洩露。其原因是vc6.0的控制台專案預設配置是靜態鏈結crt庫(單執行緒版,後面會介紹)。

動態版(dll)和靜態版(lib)c和c++執行庫的優缺點

因為靜態版必須把c和c++執行庫複製到目標程式中,所以產生的可執行檔案會比較大。同時對於使用多個模組的大型軟體來說,如果每個模組均選擇靜態鏈結c或c++執行庫,在程式執行時就會存在多個執行庫。在鏈結時也會出現重複定義的問題,如文章首第一張圖所示。

使用dll版的c和c++執行庫,程式在執行時動態的載入對應的dll。程式體積變小,但乙個很大的問題就是一旦找不到對應dll,程式將無法執行。假設使用vc6.0並選擇使用md選項構建,那麼當使用者使用vc2005來使用這個dll時很可能出現找不到msvcrt.dll或msvcp60.dll的情況。

在這裡介紹乙個很好的工具:dependency walker,可以用來分析dll的依賴關係,同時檢視dll匯出的函式,使用方法請google。

使用該工具開啟msvcrt.dll,如下圖:

我們可以在其中找到我們經常使用使用的c函式,如printf ,getchar,malloc等。

開啟msvcp100.dll,也可以找到這些c函式:

在開發的過程中我們也會遇到如下圖的鏈結錯誤,libcd.lib究竟是何方神聖呢?

它其實是libc.lib的除錯版,而libc.lib是只有在vc6.0才會使用的靜態庫,該庫是crt的單執行緒版,用於支援單執行緒版本的crt。vc2005等更高版本的編譯器已經不再提供單執行緒版本,轉而使用多執行緒版的msvcr80.dll或libcmt.lib。

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

你所不知道的C和C 執行庫

你所不知道的c和c 執行庫 周五晚,小雨,少見的未加班。無聊,遂準備寫一篇部落格,介紹一下c和c 執行庫,只因發現工作幾年的人對此一知半解的大有人在。初學者面對這些錯誤常常不知所錯 libcmt.lib是什麼東西?msvcrtd.dll又是幹嗎用的?在使用vc 時我們也常常對下面的執行庫配置項感到疑...

你所不知道的 const

const 常量是不可修改的,也就是說only read,例如 const int nbuffsize 512 nbuffsize 0 error就是因為const 常量不能修改,所以定義時必須初始化預設在全域性作用域中定義的非const變數可以在整個程式中訪問,例如 int ncounter ex...

你所不知道的background

今天要說說css中background這個屬性裡面的大學問。在乙個宣告中設定所有的背景屬性 body 看到這串 你怕了嗎?知道他們都代表啥意思嘛?不要捉急,來看展開式。展開式 background color設定元素的背景顏色,不能設定到外邊距,可以繼承父級的背景顏色,預設為透明。backgroun...