1. 程式人生 > >執行時庫MT、MTd、MD、MDd的研究

執行時庫MT、MTd、MD、MDd的研究

在開發window程式是經常會遇到編譯好好的程式拿到另一臺機器上面無法執行的情況,這一般是由於另一臺機器上面沒有安裝響應的執行時庫導致的,那麼這個與編譯選項MT、MTd、MD、MDd有什麼關係呢?這是msdn上面的解釋:

MTmutithread,多執行緒庫,編譯器會從執行時庫裡面選擇多執行緒靜態連線庫來解釋程式中的程式碼,即連線LIBCMT.lib庫

MTdmutithread+debug,多執行緒除錯版,連線LIBMITD.lib庫

MDMT+DLL,多執行緒動態庫,連線MSVCRT.lib庫,這是個匯入庫,對應動態庫為MSVCRT.dll

MDd MT+DLL+debug,多執行緒動態除錯庫,連線MSVCRTD.lib庫,對應動態庫為MSVCRTD.dll

開發多執行緒程式時(單執行緒本文不做討論),需要選擇MT、MTd、MD、MDd其中的一個。

對於MT/MTd,由於連線執行時庫是LIBCMT.lib/LIBCMTD.lib,這兩個庫是靜態庫,所以此種方式編譯的程式,移到另一臺機器上面也可以正常執行。

但是對於MD/MDd,連線的是動態庫,所以如果另一臺機器上沒有MSVCRT.dll/MSVCRTD.dll時,就提示缺少動態庫這樣的錯誤。

曾經犯這樣的錯誤,以為以MT/MTd方式編譯,程式對所有的庫都是靜態連結的,其實錯了,它只能決定執行時庫是動態連結還是靜態連結,對使用者自己寫的庫或其他第三方庫,其連線方式取決於程式碼(顯示連線動態庫Loadlibrary)或所提供的lib檔案(為匯入庫還是靜態庫),移動程式到別的機器上時,還是要帶上所需要的動態庫的。

來看一個例子,編譯一個靜態庫和一個動態庫,均實現兩個整數相加的功能:

  1. // adds.h
  2. // add後面加個s代表靜態庫
  3. #pragma once
  4. int add(int,int);  
  1. // adds.cpp
  2. // 靜態庫
  3. #include "adds.h"
  4. int add(int a, int b)  
  5. {  
  6.     return a+b;  
  7. }  
  8. 以上,執行時庫選擇MTd,編譯成靜態庫adds.lib  
  1. // addd.h
  2. // add後面加d代表動態庫
  3. #pragma once
  4. #ifndef MYLIB_API
  5. #define MYLIB_API _declspec(dllexport)
  6. #endif
  7. MYLIB_API int  add(int,int);  
  1. // addd.cpp
  2. // 動態庫
  3. #include "addd.h"
  4. int add(int a, int b)  
  5. {  
  6.   return a+b;  
  7. }以上,執行時庫選擇MTd,編譯成動態庫addd.lib, addd.dll  
  1. // test.cpp
  2. // 測試程式
  3. #include <iostream>
  4. // 測試靜態庫,此處為1,測試動態庫,此處為0
  5. #define TEST_STATIC_LINK 1
  6. #if TEST_STATIC_LINK 
  7.   #include <adds.h>
  8. #else
  9.   #define MYLIB_API _declspec(dllimport)
  10.   #include "addd.h"
  11. #endif
  12. usingnamespace std;  
  13. int main()  
  14. {  
  15.     cout << add(2,3) << endl;  
  16.     return 0;  
  17. }測試程式以MTd編譯  

1. 測試靜態庫,TEST_STATIC_LINK 定義為1,提供adds.lib,生成可執行檔案,移動到另一臺機器上可以執行,因為測試程式和adds.lib均靜態連線執行時庫

2. 測試動態庫,TEST_STATIC_LINK 定義為0,提供addd.lib,生成可執行檔案,移動到另一臺機器上可以執行,但需要addd.dll,因為addd庫靜態連線執行時庫,測試程式靜態連線執行時庫,動態連線addd庫

在上面的例子中add庫和測試程式均選擇MTd執行時庫,若不一致會導致一些編譯連線錯誤,讓新手不著頭腦。

比如adds選擇MDd,連線將會出現這樣的錯誤:

1>正在連結...

1>MSVCRTD.lib(ti_inst.obj) : error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" ([email protected]@[email protected]@@Z) 已經在LIBCMTD.lib(typinfo.obj) 中定義

1>MSVCRTD.lib(ti_inst.obj) : error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" ([email protected]@[email protected]@@Z) 已經在LIBCMTD.lib(typinfo.obj) 中定義

即一個程式中混合了不同的執行時庫(靜態庫和動態庫,除錯庫和非除錯庫),可能會產生衝突,所以一個程式中應該使用相同的執行時庫。

引用資料:

相關推薦

Qt在pro中設定執行MTMTdMDMDd,只適合VS版本的Qt

轉自:http://blog.csdn.net/caoshangpa/article/details/51416077 一.在pro中設定執行時庫 最近在用Qt5.6.0(VS2013版本)呼叫一份用Visual Studio 2013編譯的Debug版本靜態庫時出現如下錯誤:

執行MTMTdMDMDd研究

在開發window程式是經常會遇到編譯好好的程式拿到另一臺機器上面無法執行的情況,這一般是由於另一臺機器上面沒有安裝響應的執行時庫導致的,那麼這個與編譯選項MT、MTd、MD、MDd有什麼關係呢?這是msdn上面的解釋: MT:mutithread,多執行緒庫,編譯器會

執行 /MT /MTD /MD /MDD

轉載自:http://qimo601.iteye.com/blog/1550348 這裡總結下他們的區別,後面的那個'd'是代表DEBUG版本,沒有'd'的就是RELEASE版本了。 首先說/MT /MT是 "multithread, static version

執行 MT\MD的區分和優劣

  VC專案屬性→配置屬性→C/C++→程式碼生成→執行時庫 可以採用的方式有:多執行緒(/MT)、多執行緒除錯(/MTd)、多執行緒DLL(/MD)、多執行緒除錯DLL(/MDd)、單執行緒(/ML)、單執行緒除錯(/MLd)。 Reusable Library&nb

VC 執行 /MD/MDd 和 /MT/MTd

有段時間在寫cuda程式是出現過 error LNK2005: _exit 已經在 MSVCRTD.lib(MSVCR71D.dll) 中定義 等類似錯誤 原因應該是在vs2010 工程屬性中 c/c++的程式碼生成(code generation)中的設定與cuda

GCC編譯連結執行查詢順序(最真實可信)

參考了不少資料,其中最靠譜是這個:http://www.mingw.org/wiki/librarypathhowto和http://www.kaizou.org/2015/01/linux-libraries/經過線上實際驗證,GCC編譯、連結、執行時庫查詢順序如下,這個順

【VS開發】MFC執行與debugrelease版本之間的配置關係

參考內容:  前段時間從網上下來一個有意思的程式碼,用VS2010開啟時需要將工程轉換為2010的工程,轉化後卻出現了編譯不通過的問題,類似這樣的錯誤:c:\program files\microsoft visual studio 10.0\vc\atlmfc\inc

[轉]C和C++執行

轉自csdn原文:https://blog.csdn.net/ithzhang/article/details/20160009 圖片請去原文檢視 在使用VC構建專案時,經常會遇到下面的連結錯誤:   初學者面對這些錯誤常常不知所錯:libcmt.lib是什麼東西?msvcrtd.dll又是幹嗎用的?在

什麼是c執行

nafxcw.lib 和 libcmt.lib衝突問題。 解決辦法: 屬性設定裡讓程式先找到nafxcw.lib. 解決辦法參考:https://www.cnblogs.com/suiyingjie/archive/2012/10/29/2745031.html 從vs2008 工程

判斷是否已經安裝vc2008執行

Visual C++ Redistributable(簡稱VC執行庫),現在的系統VC2005是必須安裝,QQ、遊戲、網路應用都離不開VC2005的支援,(也就是說VC不安裝這些都不能用),VC2008執行庫呢是可選的,現在或將來新遊戲都依賴VC2008程式碼呢沒什麼精闢之處

終於理解了什麼是c/c++執行,以及libcmt msvcrt等內容

在各個版本的編譯器中,我們可以通過配置選項來設定程式使用的C和C++執行時庫的型別。如下圖(其他版本編譯器大同小異):MT選項:連結LIB版的C和C++執行庫。在連結時就會在將C和C++執行時庫整合到程式中成為程式中的程式碼,程式體積會變大。 MTd選項:LIB的除錯版。 M

執行路徑指定

這裡補充一點,動態庫(.so)是直接可以呼叫的,並不會被編譯程序序。只讀檔案系統,將其中一個目錄通過nfs方式mount到其它地方(比如PC機),將動態庫放於該目錄下,並將該目錄指定為庫的搜尋路徑(export LD_LIBRARY_PATH=),程式執行時會呼

VS的執行(Runtime lIB)

在開發window程式是經常會遇到編譯好好的程式拿到另一臺機器上面無法執行的情況,這一般是由於另一臺機器上面沒有安裝響應的執行時庫導致的,那麼這個與編譯選項MT、MTd、MD、MDd有什麼關係呢?這是msdn上面的解釋: MT:mutithread,多執行緒庫

C執行(C Run-time Library)詳解

一、什麼是C執行時庫1)C執行時庫就是 C run-time library,是 C 而非 C++ 語言世界的概念:取這個名字就是因為你的 C 程式執行時需要這些庫中的函式.2)C 語言是所謂的“小核心”語言,就其語言本身來說很小(不多的關鍵字,程式流程控制,資料型別等);所以,C 語言核心開發出來之後,De

CRT(C Runtime Library)—— C/C++執行

C runtime library(part of the C standard library) 任何一個 C 程式,它的背後都有一套龐大的程式碼來進行支撐,使得該程式得以執行在更高級別上,而不必擔心同計算機底層操作的細節,這套程式碼至少包括:

VS執行下載地址

Microsoft Visual C++ 2008 SP1 Redistributable Package (x86) 地址:http://www.microsoft.com/en-us/download/details.aspx?id=5582 Microsoft Vi

C/C++執行到底在Windows中起什麼作用(猜想)

以下是作者的一些猜想: 1. 我們在用VC程式設計時,會在執行我們的main函式前,系統先通過Kernel32呼叫一些函式,執行一些C的初始化準備工作,我們一般叫C執行時庫的初始化。那麼這些初始化的作用是什麼?是否是必要的?不知道大家有沒有思考過這個問題。 以下是我對這

vs2015部署---下一代VC執行系統:the Universal CRT

前言 其實the Universal CRT(通用C執行時庫)已經不能算是“下一代”,因為它已經在前兩年伴隨著Visual Studio 2015和Windows10釋出。但是由於之前使用VS2015開發的應用還較少,關注的人也少,相關的文章更少。所以筆者想幹脆用一篇文章,深入淺出的介紹一下Universa

FBX在Windows下執行的選擇

  有時候有寫些造福後人的文章,但往往都是說不透徹,我自己學得都不透徹.能造福一些算一些吧,以後看完了再補上.最近弄的用FBX SDK操作FBX動作檔案的東西,弄了這是第五個星期了,總算快弄完了.簡單說下庫的選擇.   如官方的說明所言,可以選擇3種使用FBX SDK的方式

C執行Visual C++ C RunTime Lib

CRT 全稱:Visual C++ C RunTime Lib 就是C執行時庫。 注: 以下內容部分引自CSDN中相關討論的帖子,並結合自己的理解整理而成。僅供參考。 1)執行時庫就是 C run-time library,是 C 而非 C++ 語言世界的概念:取這個