【MFC】LNK2005「already defined in LIBCMTD.lib」/ nafxcw.lib:ランタイムライブラリと「MFCの使用」設定の不一致を直す

【MFC】LNK2005「already defined in LIBCMTD.lib」/ nafxcw.lib:ランタイムライブラリと「MFCの使用」設定の不一致を直す

MFC プロジェクトのリンク時に、operator newoperator delete などが already defined in LIBCMTD.lib(または nafxcw.lib)と出る LNK2005 は、まず「MFC の使用」設定とランタイム ライブラリ(/MT・/MD)の組み合わせ不一致を疑います。

error LNK2005: "void * __cdecl operator new(unsigned __int64)" は既に LIBCMTD.lib(new_scalar.obj) で定義されています。
fatal error LNK1169: 1 つ以上の多重定義シンボルが見つかりました。
最初に確認する症状読む記事
「MFC の使用」と/MT/MDが合わない、または外部.libのランタイムが異なるこの記事:2つの設定と外部ライブラリを確認
スタティックMFCで、設定は合っているのにoperator newが重複するLNK2005/LNK1169とリンク順序の確認

目次

まず確認:「MFC の使用」と「ランタイム ライブラリ」を合わせる

MFC のリンク方式(静的か共有 DLL か)と、CRT のリンク方式(静的 /MT か 動的 /MD か)は、必ずそろえる必要があります。ここがずれると、CRT と MFC の両方が new / delete を定義し、重複になります。

「MFC の使用」合わせるランタイム ライブラリ
スタティック ライブラリで MFC を使用するマルチスレッド (/MT)マルチスレッド デバッグ (/MTd)
共有 DLL で MFC を使用するマルチスレッド DLL (/MD)マルチスレッド デバッグ DLL (/MDd)

エラーに出てくるライブラリ名は、どの CRT / MFC が取り込まれたかを示しています。名前から構成を逆算できます。

ライブラリ名正体
LIBCMT.lib / LIBCMTD.lib静的 CRT(/MT / /MTd)
MSVCRT.lib / MSVCRTD.lib動的 CRT(/MD / /MDd)
nafxcw.lib / nafxcwd.lib静的リンク MFC(MBCS。Release / Debug)
uafxcw.lib / uafxcwd.lib静的リンク MFC(Unicode。Release / Debug)

検証環境:Visual Studio 2026


手順1:プロジェクトの2つの設定を一致させる

まず自分のプロジェクト側を直します。2か所を見ます。

  1. プロジェクトのプロパティ → [詳細][MFC の使用] を確認します(静的か共有 DLL か)。
  2. プロパティ → [C/C++][コード生成][ランタイム ライブラリ] を、上の早見表に合わせて設定します。
Visual Studio 2026 のプロパティで 詳細 の MFC の使用設定を確認している画面
Visual Studio 2026 のプロパティで C/C++ コード生成のランタイム ライブラリ設定を確認している画面

注意点は 構成ごとに設定が分かれていることです。Debug / Releasex86 / x64 で別々に持つため、すべての構成で組み合わせが合っているか確認します。片方の構成だけ直して安心しないでください。


手順2:リンクしている外部 .lib のランタイムを疑う

自分のプロジェクト設定が正しいのにまだ出る場合は、リンクしている外部の静的ライブラリが、あなたのプロジェクトと違うランタイムでビルドされている可能性が高いです。

たとえば、あなたのアプリが 共有 DLL で MFC を使用(/MD)なのに、リンクする外部 .lib/MT でビルドされていると、その .libLIBCMT.lib を持ち込み、あなたの MSVCRT.libnew / delete が衝突します。

  • ソースがあるなら、その外部ライブラリをあなたのプロジェクトと同じランタイム設定で再ビルドします。これが最も安全です。
  • 提供元のバイナリしかないなら、対応するランタイムでビルドされた版を入手するか、提供元に確認します。

手順3:応急処置として /NODEFAULTLIB で競合 CRT を外す

外部ライブラリを再ビルドできず、すぐ通したいときだけの応急処置です。競合している側の CRT を1つに寄せます。

  1. プロパティ → [リンカー][入力][特定の既定のライブラリの無視] を開きます。
  2. エラーで「既に定義されています」と名指しされた側の CRT を1つだけ無視に追加します(例:LIBCMTD.lib)。

この指定は、内部的にはリンカーの /NODEFAULTLIB:libcmtd オプションになります。どちらを残すかは、残したいランタイム側を生かすのが原則です(共有 DLL 構成なら MSVCRT(D).lib を残し、静的 CRT 側を無視する)。

注意:CRT を混在させたまま /NODEFAULTLIB で無理にリンクを通すと、リンクは成功しても実行時にヒープやグローバル状態の不整合を起こすことがあります。恒久対策は手順1・2(設定の一致と再ビルド)です。/NODEFAULTLIB は、原因を理解したうえでの一時しのぎと考えてください。


関連記事


まとめ

  • already defined in LIBCMTD.lib 系の LNK2005 は、まず「MFC の使用」と「ランタイム ライブラリ」の組み合わせを合わせる。
  • 静的 MFC ↔ /MT(d)、共有 DLL MFC ↔ /MD(d)。全構成で確認する。
  • 設定が正しいのに出るなら、外部 .lib のランタイム違いを疑い、同じ設定で再ビルドする。
  • /NODEFAULTLIB は応急処置。混在のまま通すと実行時リスクが残る。
目次