2009-04-16 115 views
98

在Visual Studio中,有編譯標誌/ MD和/ MT,它們允許您選擇所需的哪種C運行時庫。我應該用/ MD還是/ MT編譯?

我明白實施中的差異,但我仍不確定要使用哪一個。有什麼優點/缺點?

我聽說過的/ MD的一個優點是,它允許有人更新運行時(可能會修補安全問題),我的應用程序將從此更新中受益。雖然對我來說,這幾乎看起來像一個非功能:我不希望人們更改我的運行時間,而不允許我測試新版本!

有些事情,我很好奇:

  • 這將如何影響構建時間? (推測/ MT有點慢?)
  • 其他影響是什麼?
  • 大多數人使用哪一個?
+0

更多的信息和建議可以在:http:// stackoverflow。com/questions/787216 – Weidenrinde 2009-05-13 09:00:24

回答

66

通過與/ MD動態鏈接,

  • 你有機會接觸到系統更新(或好或壞),
  • 可執行文件可以更小(因爲它沒有嵌入了庫)和
  • 我相信,DLL的代碼段至少在所有正在使用它的進程之間共享(減少所消耗的RAM總量)。

我還發現,在實踐中,當處理與不同運行時選項構建的靜態鏈接的第三方二進制只有庫時,主應用程序中的/ MT會更頻繁地導致衝突比/ MD(因爲如果C運行時被多次靜態鏈接,如果它們是不同的版本,你會遇到麻煩)。

+10

SxS會降低系統更新位數。該EXE得到宣佈,它希望它的CRT版本(想要的,不是得到 - 安全更新可能否決這個) – MSalters 2009-04-17 13:49:40

+0

這是否意味着,如果我編譯使用MD,我的計劃是依賴於某些DLL,程序會如果它在計算機上運行失敗依賴項DLL不存在的地方? – gerrytan 2013-10-03 05:09:03

14

我相信通過Visual Studio構建的項目的默認值是/ MD。

如果使用/ MT,則可執行文件將不依賴目標系統上存在的DLL。如果你在安裝程序中包裝它,它可能不會是一個問題,你可以任何方式。

我使用/ MT自己,以便我可以忽略整個DLL混亂。

P.S.正如Mr. Fooz指出的那樣,保持一致至關重要。如果你與其他庫鏈接,你需要使用他們所做的相同選項。如果您使用的是第三方DLL,幾乎可以確定您需要使用運行時庫的DLL版本。

4

http://msdn.microsoft.com/en-us/library/2kzt1wy3(VS.71).aspx從:

/MT限定_MT所以運行時例程的該特定多線程版本從標準頭(.h)文件中選擇。此選項還會導致編譯器將庫名稱LIBCMT.lib放入.obj文件,以便鏈接器將使用LIBCMT.lib來解析外部符號。要麼創建多線程程序需要/ MT或/ MD(或其調試等價物/ MTd或/ MDd)。

/MD定義_MT和_DLL,以便從標準.h文件中選擇多線程和DLL特定版本的運行時例程。此選項還會導致編譯器將庫名稱MSVCRT.lib放入.obj文件中。

使用此選項編譯的應用程序靜態鏈接到MSVCRT.lib。這個庫提供了一個允許鏈接器解析外部引用的代碼層。實際的工作代碼包含在MSVCR71.DLL中,它必須在運行時可用於鏈接到MSVCRT.lib的應用程序。

當/ MD與定義的_STATIC_CPPLIB(/ D_STATIC_CPPLIB)一起使用時,它將導致應用程序與靜態多線程標準C++庫(libcpmt.lib)而不是動態版本(msvcprt.lib)鏈接,但仍然動態鏈接到主CRT通過msvcrt.lib。

所以,如果我解釋它正確,則/MT鏈接靜態和/MD鏈接動態。

9

我更喜歡靜態鏈接到/ MT。

即使您使用/ MD獲得較小的可執行文件,仍然必須發佈一堆DLL以確保用戶獲得正確的版本以運行程序。最後你的安裝程序會比使用/ MT連接時更大。

更糟糕的是,如果您選擇將運行時庫放在Windows目錄中,用戶遲早會安裝具有不同庫的新應用程序,並且運氣不好會破壞應用程序。

6

使用/ MD時遇到的問題是CRT的目標版本可能不在用戶計算機上(尤其是如果您使用的是最新版本的Visual Studio並且用戶具有較舊的操作系統) 。

在這種情況下,你必須弄清楚如何在他們的機器上獲得正確的版本。

26

如果您使用DLL,那麼你應該去動態鏈接CRT(/ MD)。

如果您爲.exe和所有.dll使用動態CRT,那麼它們將共享一個CRT的實現 - 這意味着它們將共享一個CRT堆並將內存分配到一個.exe/.dll可以被釋放在另一個。

如果您爲.exe和所有.dll文件使用靜態CRT,那麼它們將全部獲得CRT的單獨副本 - 這意味着它們都將使用自己的CRT堆,因此內存必須在相同空間中釋放分配給它的模塊。你還會遇到代碼膨脹(CRT的多個副本)和額外的運行時間開銷(每個堆從操作系統分配內存來跟蹤其狀態,並且開銷可能很明顯)。

1

如果您正在構建使用其他dll或libs的可執行文件,而不是/ MD選項,那麼所有組件都將共享相同的庫。當然,這個選項應該適用於所有涉及的模塊,即dll/lib/exe。

如果您的可執行文件不使用任何lib或dll比其他人的電話。現在差別不大,因爲分享方面沒有發揮作用。

所以,也許你可以用/ MT啓動應用程序,因爲除此之外沒有任何強制性的理由,但是當它添加lib或dll的時候,你可以用lib/dll更改爲/ MD,這很容易。