すべてを定義解除するのではなく、最初から定義しないようにします。これを行うには、モジュールの最初の部分を (別のソース ファイルとして) 明示的にプリプロセッサに渡し、元のソース コードではなくプリプロセッサの出力をモジュールのメイン ソース ファイルに含めます。
Visual Studio 2010 を使用してこれを試してみました。試しに、3 つのソース ファイルを作成しました。これは、サンプル コードの最初の部分に類似した headers.cpp です。
namespace os_stuff
{
#undef _MSC_EXTENSIONS
#define _WIN32_WINNT 0x0601
#include <windows.h>
}
#include "xyzzy.h"
は、名前空間内からファイルを含めるとエラーが発生するため#undef _MSC_EXTENSIONS
、 が含まれないようにするためのものです。sourceannotations.h
これは xyzzy.h で、サンプル コードから「ここに多数のファイルを含める」ことを示しています。
os_stuff::DWORD myFunction(os_stuff::HANDLE h);
これは test.cpp で、サンプル コードの「すべてクリーン」な部分に似ています。
#include "headers.h"
int main(int argc, char ** argv)
{
os_stuff::DWORD UNALIGNED;
os_stuff::HANDLE h = 0;
UNALIGNED = myFunction(h);
return UNALIGNED;
}
UNALIGNED を変数名として使用していることに注意してください。これは、意味があるからではなく、windows.h
直接含めた場合に機能しないものの例として (__unaligned キーワードに展開されるため) にすぎません。
Visual Studio 2010 コマンド ラインから、次のheaders.h
ように作成します。
cl /P headers.cpp /Fiheaders.h
/P オプションについては、こちらに記載されています。
test.cpp
その後、通常の方法でコンパイルできます。
cl test.cpp
(明らかに、この場合、myFunction を定義していないため、プログラムはリンクしませんが、完全に問題なくコンパイルされます。)
headers.h
コマンド ラインから実行するよりも、ビルドを自動化するほうが、少し手を加えるだけでそれほど難しくないはずです。
一部の C++ コンパイラでは、プリプロセッサは実際には個別の実行可能ファイル (これは従来のモデルでした) ですが、そうでない場合でも、コンパイラを起動せずにプリプロセッサを実行するだけのオプションがあるはずです。