VC執行庫 ( MT MD 等)

2021-07-05 05:40:30 字數 4040 閱讀 7649

由於老是混淆這些概念,特轉此微博。

vc專案屬性

→配置屬性→c/c++→**生成→執行時庫 可以採用的方式有:多執行緒(/mt)、多執行緒除錯(/mtd)、多執行緒dll(/md)、多執行緒除錯dll(/mdd)、

單執行緒(/ml)、單執行緒除錯(/mld)。

reusable library

switch

library

macro(s) defined

single threaded

/mllibc

(none)

static multithread

/mtlibcmt

_mtdynamic link (dll)

/mdmsvcrt

_mt and _dll

debug single threaded

/mld

libcd

_debug

debug static multithread

/mtd

libcmtd

_debug and _mt

debug dynamic link (dll)

/mdd

msvcrtd

_debug, _mt, and _dll

其中以小寫「d」結尾的選項表示的debug版本的,沒有「d」的為release版本。大型專案中必須要求所有元件和第三方庫的執行時庫是統一的,否則將會出現lnk2005井噴。

單執行緒執行時庫選項/ml和/mld在vs2003以後就被廢了。

/mt和/mtd表示採用多執行緒crt庫的靜態lib版本。該選項會在編譯時將執行時庫以靜態lib的形式完全嵌入。該選項生成的可執行檔案執行時不需要執行時庫dll的參加,會獲得輕微的效能提公升,但最終生成的二進位制**因鏈入龐大的執行時庫實現而變得非常臃腫。當某專案以靜態鏈結庫的形式嵌入到多個專案,則可能造成執行時庫的記憶體管理有多份,最終將導致致命的「invalid address specified to rtlvalidateheap」問題。另外託管c++和cli中不再支援/mt和/mtd選項。

/md和/mdd表示採用多執行緒crt庫的動態dll版本,會使應用程式使用執行時庫特定版本的多執行緒dll。鏈結時將按照傳統vc鏈結dll的方式將執行時庫msvcrxx.dll的導入庫msvcrt.lib鏈結,在執行時要求安裝了相應版本的vc執行時庫可再發行元件包(當然把這些執行時庫dll放在應用程式目錄下也是可以的)。 因/md和/mdd方式不會將執行時庫鏈結到可執行檔案內部,可有效減少可執行檔案尺寸。當多專案以md方式運作時,其內部會採用同乙個堆,記憶體管理將被簡化,跨模組記憶體管理問題也能得到緩解。

結論:/md和/mdd將是潮流所趨,/ml和/mld方式請及時放棄,/mt和/mtd在非必要時最好也不要採用了。

以前經常遇到這個警告資訊,因為執行並沒有什麼問題,所以也沒深究。但是耿耿於懷那個「 0 個錯誤,0 個警告」的成功提示,在網上搜了一下。原來問題出在預設庫的引用選擇上。

vs2008,專案——屬性——配置屬性——c/c++——**生成:他有/mt,/mtd,/md,/mdd四個選項,你必須讓所有使用的庫都使用相同的配置,否則就會有相應的提示,甚至可能會出現無法解析的函式。有時我們使用的庫不是自己可以控制的,那麼就只能把工程屬性設定成河你使用的庫相同的選項。

錯誤 1 error lnk2005: _free 已經在 libcmtd.lib(dbgheap.obj) 中定義         msvcrt.lib

錯誤 2 error lnk2005: _malloc 已經在 libcmtd.lib(dbgheap.obj) 中定義     msvcrt.lib 

.....

如果有一堆的重定義錯誤發生在同乙個lib中,而且跟它衝突的也是同乙個lib,那麼這個兩個lib的功能應該是一樣的,可以2選一,只要在「忽略特定的庫」內填入需要忽略的庫。

專案屬性-配置屬性-鏈結器-輸入-忽略特定的庫:libcmtd.lib

專案屬性-配置屬性-常規-mfc的使用:在共享 dll 中使用 mfc

msvcrt.lib 和libcmt.lib的衝突還是比較常見的。

從錯誤資訊可以看出是msvcrt.lib和libcmt.lib庫中重複定義了__isctype等符號。為什麼會出現這樣的問題呢?這就要從這兩個庫的作用說起了。

msvcrt.lib是vc中的multithreaded dll 版本的c執行時庫,而libcmt.lib是multithreaded的執行時庫。在同乙個專案中,所有的原始檔必須鏈結相同的c執行時庫。如果某一文 件用了multithreaded dll版本,而其他檔案用了single-threaded或者multithreaded版本的庫,也就是說用了不同的庫,就會導致這個警告的出現。

告警資訊的意思我們明白之後,就要找造成這個問題的原因了。在專案設定中我們可以看到當前專案使用的是multithreaded非dll版本的運 行時庫,這說明專案中還有其他檔案用到了不是這個版本的執行時庫。很顯然,就是openssl的靜態庫。檢視openssl中ms下的nt.mak,我們 可以發現靜態庫版本中openssl使用編譯開關/md進行編譯的,也就是說openssl靜態庫是預設用的multithreaded dll 版本的c執行時庫。

原因找到了。那麼解決方法,很明顯有兩個。總之就是將兩個專案的執行時庫統一。

簡單的方式就是將專案的動態庫修改為使用multithreaded dll 版本的c執行時庫即可。 

某些情況下你的專案可能不能改變當前的執行時庫,你可以將openssl的nt.mak中的/md開關修改為/mt然後重新編譯openssl靜態庫就可以了。

預設庫「library」與其他庫的使用衝突;請使用 /nodefaultlib:library lnk4098 的解決辦法

您試圖與不相容的庫鏈結。 

注意 執行時庫現在包含可防止混合不同型別的指令。如果試圖在同乙個程式中使用不同型別的執行 時庫或使用除錯和非除錯版本的執行時庫,則將收到此警告。例如,如 果編譯乙個檔案以使用一種執行時庫,而編譯另乙個檔案以使用另一種執行時庫(例如單執行緒執行時庫對多執行緒執行時庫),並試圖鏈結它們,則將得到此警告。應 將所有原始檔編譯為使用同乙個執行時庫。有關更多資訊,請參見使用執行時庫(/md、/mt 和 /ld)編譯器選項。 

可以 使用鏈結器的 /verbose:lib 開關來確定鏈結器搜尋的庫。如果收到 lnk4098,並想建立使用如單執行緒、非除錯執行時庫的可執行檔案,請使用 /verbose:lib 選項確定鏈結器搜尋的庫。鏈結器作為搜尋的庫輸出的應是 libc.lib,而非 libcmt.lib、msvcrt.lib、libcd.lib、libcmtd.lib 和 msvcrtd.lib。對每個要忽略的庫可以使用 /nodefaultlib,以通知鏈結器忽略錯誤的執行時庫。 

下表顯示根據要使用的執行時庫應忽略的庫。 

若要使用第一行執行時庫    請忽略第2行的這些庫 

單執行緒 (libc.lib) 

libcmt.lib、msvcrt.lib、libcd.lib、libcmtd.lib、msvcrtd.lib 

多執行緒 (libcmt.lib) 

libc.lib、msvcrt.lib、libcd.lib、libcmtd.lib、msvcrtd.lib 

使用 dll 的多執行緒 (msvcrt.lib) 

libc.lib、libcmt.lib、libcd.lib、libcmtd.lib、msvcrtd.lib 

除錯單執行緒 (libcd.lib) 

libc.lib、libcmt.lib、msvcrt.lib、libcmtd.lib、msvcrtd.lib 

除錯多執行緒 (libcmtd.lib) 

libc.lib、libcmt.lib、msvcrt.lib、libcd.lib、msvcrtd.lib 

使用 dll 的除錯多執行緒 (msvcrtd.lib) 

libc.lib、libcmt.lib、msvcrt.lib、libcd.lib、libcmtd.lib 

例如,如果收到此警告,並希望建立使用非除錯、單執行緒版本的執行時庫的可執行檔案,可以將下列選項與鏈結器一起使用: 

/nodefaultlib:libcmt.lib /nodefaultlib:msvcrt.lib /nodefaultlib:libcd.lib /nodefaultlib:libcmtd.lib /nodefaultlib:msvcrtd.lib

VS 執行庫MT MD的區別

vc專案屬性 配置屬性 c c 生成 執行時庫 可以採用的方式有 多執行緒 mt 多執行緒除錯 mtd 多執行緒dll md 多執行緒除錯dll mdd 單執行緒 ml 單執行緒除錯 mld 目前win7 win10等,選擇md問題不大,但是xp等一些比較老的系統需要選擇mt mt是 multith...

VS 執行庫MT MD的區別

vc專案屬性 配置屬性 c c 生成 執行時庫 可以採用的方式有 多執行緒 mt 多執行緒除錯 mtd 多執行緒dll md 多執行緒除錯dll mdd 單執行緒 ml 單執行緒除錯 mld 目前win7 win10等,選擇md問題不大,但是xp等一些比較老的系統需要選擇mt mt是 multith...

mysql vc執行庫 VC 執行庫安裝

vc 執行庫 visual c 可再發行程式包 是執行使用相應版本的 visual c 開發的應用程式時必要的元件。wampserver內建的apache mysql mariadb和php就依賴vc 執行庫,所以我們需要在電腦上安裝好vc 執行庫,否則無法正常使用wampserver。wampse...