262

この警告:

LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts
  with use of other libs; use /NODEFAULTLIB:library

Visual Studio ではかなり一般的な警告です。その正確な理由と、それを処理する正しい方法 (もしあれば) を理解したいと思います。

これは、でコンパイルされたデバッグ ビルドで表示され/MDdます。プロジェクトは、ウィンドウVersion.dllなどにリンクされており、pdh.dllそれ自体が にリンクしていMSVCRT.dllます。明らかに、これらのデバッグ バージョンがなく、コンパイルできません。

そのため、リンカーのコマンドラインに追加/NODEFAULTLIB:MSVCRTしたところ、実際に警告が削除されました。しかし、これは実際に何をするのでしょうか? そして、なぜそれが必要なのですか?

4

5 に答える 5

304

vc\lib には、CRT リンク ライブラリの 4 つのバージョンがあります。

  • libcmt.lib: リリース ビルド用の静的 CRT リンク ライブラリ (/MT)
  • libcmtd.lib: デバッグ ビルド用の静的 CRT リンク ライブラリ (/MTd)
  • msvcrt.lib: CRT (/MD) のリリース DLL バージョンのインポート ライブラリ
  • msvcrtd.lib: CRT のデバッグ DLL バージョンのインポート ライブラリ (/MDd)

リンカー オプション、プロジェクト + プロパティ、リンカー、コマンド ラインを見てください。これらのライブラリがここで言及されていないことに注意してください。リンカは、コンパイラによってどの /M スイッチが使用されたか、および #pragma コメント ディレクティブを使用してどの .lib をリンクする必要があるかを自動的に判断します。ちょっと重要なことですが、/M オプションとリンクする .lib の間に不一致があると、恐ろしいリンク エラーが発生し、実行時エラーを診断するのが難しくなります。

リンカが msvcrt.libとlibcmt.libの両方にリンクするように指示されると、引用したエラー メッセージが表示されます。これは、/MT でコンパイルされたコードを /MD でリンクされたコードとリンクすると発生します。CRT のバージョンは 1 つだけです。

/NODEFAULTLIB は、/MT コンパイル コードから生成された #pragma コメント ディレクティブを無視するようにリンカーに指示します。これは機能する可能性がありますが、他の多くのリンカー エラーは珍しくありません。静的 CRT バージョンでは extern int ですが、DLL バージョンでは関数にマクロ化されているerrnoのようなもの。他の多くの人はそれが好きです。

さて、この問題を正しい方法で修正し、間違った /M オプションでコンパイルされた、リンクしている .obj または .lib ファイルを見つけます。手がかりがない場合は、「/ MT」の.obj/.libファイルをgrepすることで見つけることができます

ところで、Windows 実行可能ファイル (version.dll など) には、ジョブを完了するための独自の CRT バージョンがあります。これは c:\windows\system32 にあります。独自のプログラムで確実に使用することはできません。その CRT ヘッダーはどこにもありません。プログラムで使用される CRT DLL の名前が異なります (msvcrt90.dll など)。

于 2010-06-09T16:43:02.647 に答える
54

これは、依存する dll の 1 つが別のランタイム ライブラリでコンパイルされていることを意味します。

プロジェクト -> プロパティ -> C/C++ -> コード生成 -> ランタイム ライブラリ

すべてのライブラリを調べて、それらが同じ方法でコンパイルされていることを確認してください。

このリンクのこのエラーの詳細:

警告 LNK4098: defaultlib "LIBCD" は他のライブラリの使用と競合します

于 2011-04-11T12:30:57.050 に答える
33

IMO Yochai Timmerからのこのリンクは非常に適切で関連性がありましたが、読むのが苦痛でした。あらすじを書きました。

Yochai、これを読んだことがあるなら、最後のメモを見てください。


元の投稿を読む: warning LNK4098: defaultlib "LIBCD" conflicts with use of other libs

エラー

リンク: 警告 LNK4098: defaultlib "LIBCD" は他のライブラリの使用と競合します。/NODEFAULTLIB:ライブラリを使用

意味

システムの一部は、静的にリンクされたデバッグ情報 (libcd) を含むシングル スレッド標準 (libc) ライブラリを使用するようにコンパイルされました。

システムの別の部分は、デバッグ情報なしでマルチスレッドの標準ライブラリを使用するようにコンパイルされましたが、これは DLL に常駐し、動的リンクを使用します。

解決方法

  • 警告は無視してください。結局のところ、これは単なる警告です。ただし、プログラムには同じ関数の複数のインスタンスが含まれています。

  • リンカー オプション /NODEFAULTLIB:lib を使用します。これは完全な解決策ではありません。プログラムをこのようにリンクさせることができたとしても、警告サインを無視しています。コードはさまざまな環境用にコンパイルされています。コードの一部はシングル スレッド モデル用にコンパイルされ、他のコードはコンパイルされている可能性があります。マルチスレッド。

  • [...] すべてのライブラリを調べて、正しいリンク設定があることを確認します

後者では、元の投稿で述べたように、2 つの一般的な問題が発生する可能性があります。

  • アプリケーションに別の方法でリンクされているサードパーティのライブラリがあります。

  • コードに他のディレクティブが埋め込まれています。通常、これは MFC です。システム内のモジュールが MFC に対してリンクしている場合、すべてのモジュールは名目上、同じバージョンの MFC に対してリンクする必要があります。

そのような場合は、問題を理解し、解決策を決定してください。


注 : Yochai Timmer のリンクの要約を彼自身の回答に含めたかったのですが、編集を適切に確認するのが難しい人もいるため、別の回答に書く必要がありました。ごめん

于 2013-12-18T05:13:35.903 に答える
8

VC++ でアプリケーションを作成するたびに、これを取得します。

プロジェクトを右クリックし、[プロパティ] を選択してから、[構成プロパティ | C/C++ | [コード生成] で、デバッグ構成に [マルチスレッド デバッグ (/MTd)] を選択します。

これはリリース構成の設定を変更しないことに注意してください。同じ場所に移動して、リリースに「マルチスレッド (/MT)」を選択する必要があります。

于 2012-05-31T20:21:53.810 に答える