/ MDまたは/ MTでコンパイルする必要がありますか?


126

Visual Studioには、コンパイルフラグ/ MDおよび/ MTがあり、必要なCランタイムライブラリの種類を選択できます。

実装の違いは理解していますが、どちらを使用するかはまだわかりません。長所/短所は何ですか?

私が聞いた/ MDの利点の1つは、これにより、誰かがランタイムを更新できるようになり(セキュリティの問題にパッチを当てるなど)、私のアプリがこの更新から恩恵を受けることです。私にとっては、これはほとんど機能ではないように見えます。新しいバージョンに対してテストすることを許可しない限り、ランタイムを変更したくないのです。

気になる点:

  • これはビルド時間にどのように影響しますか?(おそらく/ MTは少し遅いですか?)
  • 他の影響は何ですか?
  • ほとんどの人はどちらを使用しますか?

1
詳細情報と提案は、stackoverflow.com
questions / 787216

回答:


85

/ MDと動的にリンクすることにより、

  • あなたはシステムアップデート(良いか悪いか)にさらされています、
  • 実行可能ファイルを小さくすることができます(ライブラリが埋め込まれていないため)。
  • DLLのコードセグメントは、少なくともDLLをアクティブに使用しているすべてのプロセス間で共有されていると思います(消費されるRAMの総量を減らします)。

また、実際には、さまざまなランタイムオプションでビルドされた静的にリンクされたサードパーティのバイナリのみのライブラリを操作する場合、メインアプリケーションの/ MTは/ MDよりも頻繁に競合を引き起こす傾向があることもわかりました( Cランタイムが静的に複数回リンクされている場合、特にバージョンが異なる場合、問題が発生します)。


10
システム更新ビットはSxSによって多少削減されます。EXEは必要なCRTバージョンを宣言します(取得しないで欲しい-セキュリティ更新がこれを無効にする可能性があります)
MSalters 2009

1
これは、MDを使用してコンパイルし、プログラムが一部のdllに依存している場合、依存関係dllが存在しないコンピューターで実行するとプログラムが失敗することを意味しますか?
gerrytan 2013年

5
@gerrytan:はい、使用する適切なDLLがソフトウェアを実行するすべてのコンピューターに存在することを確認する必要があります。これに対する一般的な解決策は、ユーザーに適切なMSVC再頒布可能パッケージをインストールさせるか、すべての作業を行うインストーラーを使用することです。
Mr Fooz 2013年

@Royiわかりませんが/MT、ランタイムアプリは毎回ランタイム関数の実装を検索する必要がないため、実行時は少し速くなると思います。私はこのレベルの専門家ではありませんが、ほとんどの場合、 OSはランタイム実装をキャッシュするため、アプリはキャッシュされたバージョンを使用します。そのため、違いはそれほど大きくありません。このコメントを引数として取らないでください。
アハメド・カマル

34

DLLを使用している場合は、動的にリンクされたCRT(/ MD)を使用する必要があります。

.exeとすべての.dllに動的CRTを使用する場合、それらはすべてCRTの単一の実装を共有します。つまり、すべてが単一のCRTヒープを共有し、1つの.exe / .dllに割り当てられたメモリを解放できます。別の。

.exeとすべての.dllに静的CRTを使用する場合、それらはすべてCRTの個別のコピーを取得します。つまり、すべてが独自のCRTヒープを使用するため、メモリは同じモジュールで解放する必要があります。割り当てられました。また、コードの膨張(CRTの複数のコピー)と過剰なランタイムオーバーヘッド(各ヒープがOSからメモリを割り当ててその状態を追跡し、オーバーヘッドが顕著になる可能性があります)にも悩まされます。


20

Visual Studioでビルドしたプロジェクトのデフォルトは/ MDだと思います。

/ MTを使用する場合、実行可能ファイルは、ターゲットシステムに存在するDLLに依存しません。これをインストーラーでラップしている場合は、おそらく問題にならず、どちらの方法でもかまいません。

私は/ MTを自分で使用しているため、DLL全体の混乱を無視できます。

PS Fooz氏が指摘するように、一貫性を保つことが非常に重要です。他のライブラリとリンクしている場合は、他のライブラリと同じオプションを使用する必要があります。サードパーティのDLLを使用している場合、ランタイムライブラリのDLLバージョンを使用する必要があることはほぼ確実です。


14

/ MTと静的にリンクすることを好みます。

/ MDを使用してより小さな実行可能ファイルを取得したとしても、ユーザーがプログラムを実行するための適切なバージョンを取得できるようにするには、多数のDLLを出荷する必要があります。そして最終的に、インストーラーは/ MTとリンクする場合よりも大きくなります。

さらに悪いことに、ランタイムライブラリをWindowsディレクトリに配置することを選択した場合、遅かれ早かれ、ユーザーは別のライブラリを使用して新しいアプリケーションをインストールし、不運にもアプリケーションを破壊します。


5
「ランタイムライブラリをWindowsディレクトリに置く」ことは非常に悪い考えです。あなたがする前に同じことをした他のダムアプリケーションを壊すことができます。SxSを使用してインストーラーに処理させるか、/ MTを使用します。
MSalters 2009

1
それは悪い考えだと私は完全に同意します。一部の人はそれを行うので、私はなぜこれが良い考えではないのか説明しました。
エイドリアン・グリゴア

@AdrianGrigoreなぜ、異なるライブラリを持つ新しいアプリケーションがあなたのアプリケーションを中断させるのでしょうか?/ MDリンケージを使用する場合、ライブラリの新しいバージョンのロードを開始するだけでしょうか?
rturrado 2012

4
@rturrado:まったく違います。上に他のアプリケーションをインストールすると、dllが古いバージョンで上書きされる可能性があります。新しいバージョンはなくなります。これは一般に「dll hell」として知られています。en.wikipedia.org/ wiki / DLL_Hell
Adrian Grigore

1
Microsoftは、Visual Studio 2010のWinSxSをあきらめました。ランタイムライブラリは、非公開またはsystem32(msdn.microsoft.com/en-us/library/vstudio/dd293574.aspx)に展開されるようになりました。
BCran 2013年

8

/ MDで発生する問題は、CRTのターゲットバージョンがユーザーのマシンにない可能性があることです(特に、最新バージョンのVisual Studioを使用していて、ユーザーが古いオペレーティングシステムを使用している場合)。

その場合、あなたは彼らのマシンに正しいバージョンを取得する方法を理解する必要があります。


7

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

/ MTランタイムルーチンのマルチスレッド固有のバージョンが標準ヘッダー(.h)ファイルから選択されるように_MTを定義します。このオプションにより、コンパイラーはライブラリー名LIBCMT.libを.objファイルに配置して、リンカーがLIBCMT.libを使用して外部シンボルを解決するようにします。マルチスレッドプログラムを作成するには、/ MTまたは/ MD(またはそれらに相当する/ MTdまたは/ MDd)が必要です。

/ MD _MTと_DLLを定義して、ランタイムルーチンのマルチスレッド固有バージョンとDLL固有バージョンの両方が標準の.hファイルから選択されるようにします。このオプションにより、コンパイラーはライブラリー名MSVCRT.libを.objファイルに配置します。

このオプションでコンパイルされたアプリケーションは、MSVCRT.libに静的にリンクされます。このライブラリは、リンカーが外部参照を解決できるようにするコードのレイヤーを提供します。実際の作業コードはMSVCR71.DLLに含まれています。MSVCR71.DLLは、実行時にMSVCRT.libにリンクされたアプリケーションで使用できる必要があります。

/ MDを_STATIC_CPPLIBを定義して使用すると(/ D_STATIC_CPPLIB)、アプリケーションは動的バージョン(msvcprt.lib)ではなく静的マルチスレッド標準C ++ライブラリ(libcpmt.lib)とリンクしますが、メインCRTにはmsvcrt.lib。

したがって、正しく解釈している場合、/ MTは静的にリンクし、/ MDは動的にリンクします。


「どちらを使うべきか」という質問でしたが、これは答えではありません。
Leonard Inkret

1

/ MDオプション以外のdllまたはlibを使用する実行可能ファイルをビルドする場合は、その方法ですべてのコンポーネントが同じライブラリを共有するため、推奨されます。もちろん、このオプションは関連するすべてのモジュール、つまりdll / lib / exeに一致する必要があります。

実行可能ファイルがその誰の呼び出しよりもlibまたはdllを使用しない場合。共有の側面が機能していないので、今の違いはあまりありません。

ですから、/ MTでアプリケーションを起動することもできます。それ以外に説得力のある理由はないのですが、libまたはdllを追加するときは、lib / dllの/ MDに変更するのが簡単です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.