< Windows NT 系でデフォルトプリンタを調べる | ClassView 情報ファイルにアクセスできません。ClassView 情報が使用できません。 >

June 7, 2004

error LNK2005

MFC を使用したプロジェクトで、こんなリンクエラーがでた。

コードを生成中...
リンク中...
nafxcw.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) はすでに LIBCMT.lib(new.obj) で定義されています
nafxcw.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) はすでに LIBCMT.lib(delete.obj) で定義されています
Release/Ocrreruset.exe : fatal error LNK1169: 1 つ以上の複数回定義されているシンボルが見つかりました
link.exe の実行エラー

ググってみたら、148652 - [PRB] C ランタイム ライブラリを MFC ライブラリより先にリンクしたときの LNK2005 エラーというのが見つかった。これによると、

CRT ライブラリでは、new、delete、および DllMain の各関数で弱い外部リンケージを使用します。MFC ライブラリにも new、delete、および DllMain の各関数が含まれており、このために MFC ライブラリを CRT ライブラリより先にリンクする必要があります。

ということであるらしい。解決策として、プロジェクトの設定でリンクの「無視するライブラリ」に Nafxcwd.libLibcmtd.lib を追加し(区切りはスペースでもカンマでもいいみたい)、「オブジェクト/ライブラリ モジュール」の方で、あらためて Nafxcwd.libLibcmtd.lib の順で指定したら、その順にリンクされるからうまくいく、と書いてある。

実はこれには補足があって、Nafxcwd.lib とLibcmtd.lib はともにデバッグ用のライブラリである。なので、Release でエラーが出る場合には、それぞれ Nafxcw.lib, Libcmt.lib に読み替えて設定する必要がある。

通常、MFCを使用するプロジェクトでは、StdAfx.h をすべてのソースファイルの先頭でインクルードするが、今回はたまたま部分的にCのソースファイルを流用するために、"プリコンパイルヘッダーを使用しない"として、そのソースには StdAfx.h をインクルードしなかったためにこのリンクエラーが出た。StdAfx.h は、先頭で Afx.h をインクルードするように作られる。Afx.h は先頭で、

/////////////////////////////////////////////////////////////////////////////
// Win32 libraries

#ifndef _AFXDLL
	#ifndef _UNICODE
		#ifdef _DEBUG
			#pragma comment(lib, "nafxcwd.lib")
		#else
			#pragma comment(lib, "nafxcw.lib")
		#endif
	#else
		#ifdef _DEBUG
			#pragma comment(lib, "uafxcwd.lib")
		#else
			#pragma comment(lib, "uafxcw.lib")
		#endif
	#endif
#else
	#ifndef _UNICODE
		#ifdef _DEBUG
			#pragma comment(lib, "mfc42d.lib")
			#pragma comment(lib, "mfcs42d.lib")
		#else
			#pragma comment(lib, "mfc42.lib")
			#pragma comment(lib, "mfcs42.lib")
		#endif
	#else
		#ifdef _DEBUG
			#pragma comment(lib, "mfc42ud.lib")
			#pragma comment(lib, "mfcs42ud.lib")
		#else
			#pragma comment(lib, "mfc42u.lib")
			#pragma comment(lib, "mfcs42u.lib")
		#endif
	#endif
#endif

#ifdef _DLL
	#if !defined(_AFX_NO_DEBUG_CRT) && defined(_DEBUG)
		#pragma comment(lib, "msvcrtd.lib")
	#else
		#pragma comment(lib, "msvcrt.lib")
	#endif
#else
#ifdef _MT
	#if !defined(_AFX_NO_DEBUG_CRT) && defined(_DEBUG)
		#pragma comment(lib, "libcmtd.lib")
	#else
		#pragma comment(lib, "libcmt.lib")
	#endif
#else
	#if !defined(_AFX_NO_DEBUG_CRT) && defined(_DEBUG)
		#pragma comment(lib, "libcd.lib")
	#else
		#pragma comment(lib, "libc.lib")
	#endif
#endif
#endif

#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "gdi32.lib")
#pragma comment(lib, "comdlg32.lib")
#pragma comment(lib, "winspool.lib")
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "comctl32.lib")

てな具合で、必要なライブラリを適切な順序でリンクするようになっている。

トラックバック

このエントリーにトラックバック:
http://frog.raindrop.jp/cgi-bin/mt/mt-tb.cgi/500

コメント

コメントする

※ コメントスパム対策のため、コメント本文はおはよう、こんにちわ、こんばんわのいずれかより始めるようにしてください。

name:
email:

※ 必要ですが、表示しません。

url:
情報を保存する ?