为了整洁,我想#undef
windows.h
中定义的所有内容。
E.G:
namespace os_stuff
{
#include <windows.h>
// ARGH! Macros everywhere!
// at least I can keep the rest of the API in here
}
// include a bunch of files here that use the Windows API through os_stuff
namespace os_stuff
{
#include <unwindows.h> // <- #undefs all that was #defined in windows.h
}
// All clean, as though windows.h was never here. Though os_stuff, used nowhere else,
// still has all of the API declarations in it (which is OK).
答案 0 :(得分:2)
不要取消任何东西,而是首先避免定义它们。您可以通过preprocessor显式传递模块的第一部分(作为单独的源文件)并在模块的主源文件中包含预处理器输出而不是原始源代码来完成此操作。
我使用Visual Studio 2010尝试了这一点。在我的试用版中,我创建了三个源文件。这是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,类似于示例代码中的“all clean”部分:
#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选项为documented here。
然后您可以通常的方式编译test.cpp
:
cl test.cpp
(显然在这种情况下,程序不会链接,因为我们没有定义myFunction,但它编译得非常愉快。)
稍微摆弄它不应该太难以自动构建headers.h
而不是从命令行执行它。
在某些C ++编译器中,预处理器实际上是一个单独的可执行文件(这是传统的模型),但如果没有,那么仍然应该只运行预处理器而不调用编译器。