LNK4098 の解決: defaultlib 'MSVCRT' が Ask Question と競合しています

LNK4098 の解決: defaultlib 'MSVCRT' が Ask Question と競合しています

この警告:

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

Visual Studio では非常に一般的な警告です。その正確な理由と、適切な対処方法 (ある場合) を理解したいと思います。

これは、 でコンパイルされたデバッグ ビルドで表示されます/MDd。プロジェクトは、にリンクされているwindowsVersion.dllやなどにリンクされています。当然、これらのデバッグ バージョンは持っていないので、コンパイルできません。pdh.dllMSVCRT.dll

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

ベストアンサー1

vc\lib には CRT リンク ライブラリの 4 つのバージョンが存在します。

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

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

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

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

さて、この問題を正しく解決するには、間違った /M オプションでコンパイルされたリンク先の .obj または .lib ファイルを見つけます。見当もつかない場合は、.obj/.lib ファイルで "/MT" を grep して見つけることもできます。

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

おすすめ記事