MFCをスタティックリンクしたときに出るエラー
MFCを使う場合、MFCをDLLとして使う方法と、MFCをスタティックリンクさせて1つの実行ファイルにする方法があります。これはプロジェクト設定の「全般」の設定で設定できます。
ところが最初にDLLを使うようにプロジェクトを作成して、後からスタティックリンクするように変更すると、ビルドエラーが出るときがあります。エラーメッセージは次のようなものです。
fatal error C1189: #error : Please use the /MD switch for _AFXDLL builds |
これはafxver_.h内のプリプロセッサで出ているものですが、_AFXDLLという定義は、本来MFCをDLLで使うときにしか定義されないものです。これが何かしらの原因で定義されてしまっているため、ビルドエラーが出ているのです。
ビルドが実行された時に、どんなオプションが実際に使われたかというのは、出力フォルダにできるBuildLog.htmを見るとわかります。たとえば次のように出力されています。
コマンド ライン 一時ファイル "g:/projects/TimerTool/Debug/RSP00000D.rsp" を作成しています。内容 : [ /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FD /EHsc /RTC1 /MTd /Yc"stdafx.h" /Fp"./Debug/TimerTool.pch" /Fo"./Debug/" /Fd"./Debug/" /FR"./Debug/" /W3 /c /ZI /TP ./StdAfx.cpp ] |
これを見ると、確かにビルド時に_AFXDLLが定義されているのがわかります。(/Dオプションはビルド時に定義を追加します。#defineでソースコードに書くのと同じ効果があります。ただし/Dで定義した場合は全ソースに影響します。)
これを直すには、プロジェクト設定の「C/C++」「リンカ」「リソース」タブの「コマンドライン」を順に見ていって、"_AFXDLL"が追加されていないか確認します。追加されていたら、"プリプロセッサの定義"から"_AFXDLL"を削除します。
これでビルドしてもまだBuildLog.htmに"_AFXDLL"が出てくるときは、ソースファイル単位の定義追加がされている可能性があります。これはプロジェクトファイルを直接テキストエディタで開いて調べてみます。拡張子".vcproj"のファイルをテキストエディタで開くと、ソースファイルごとのオプション設定が記述してあるのがわかります。
ここで、<Files>セクションの中で<Tool>の中にある、"PreprocessorDefinitions"というのが、ソースファイルごとの定義追加になります。ここに"_AFXDLL"が記述してあるときは、これをすべて削除します。これでビルド時に"_AFXDLL"が定義されなくなるはずです。
... <Files> <Filter Name="Source Files" Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"> <File RelativePath="Importer.cpp"> <FileConfiguration Name="Debug|Win32"> <Tool Name="VCCLCompilerTool" PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;$(NoInherit)" BasicRuntimeChecks="3" BrowseInformation="1"/> </FileConfiguration> ... |
この問題は、VC6.0などの古いバージョンで作ったプロジェクトを.net環境に移行した場合などに起こるようです。同じパージョンで作ったプロジェクトの場合は、プロジェクトの設定だけでMFCのリンク方法が切り替えられます。