To be tidy, I want to #undef
everything defined in 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).
Rather than undefing everything, avoid defining them in the first place. You can do this by explicitly passing the first part of your module (as a separate source file) through the preprocessor and including the preprocessor output, rather than the original source code, in your module's main source file.
I tried this out using Visual Studio 2010. For my trial, I created three source files. This is headers.cpp, analogous to the first part of your sample code:
namespace os_stuff
{
#undef _MSC_EXTENSIONS
#define _WIN32_WINNT 0x0601
#include <windows.h>
}
#include "xyzzy.h"
The #undef _MSC_EXTENSIONS
is to prevent the inclusion of sourceannotations.h
, because that file generates errors when included from inside a namespace.
This is xyzzy.h, to demonstrate "include a bunch of files here" from your sample code:
os_stuff::DWORD myFunction(os_stuff::HANDLE h);
And this is test.cpp, analogous to the "all clean" part of your sample code:
#include "headers.h"
int main(int argc, char ** argv)
{
os_stuff::DWORD UNALIGNED;
os_stuff::HANDLE h = 0;
UNALIGNED = myFunction(h);
return UNALIGNED;
}
Note that we're using UNALIGNED as a variable name, not because it makes sense, but just as an example of something that won't work if you've included windows.h
directly (because it expands to the __unaligned keyword).
From a Visual Studio 2010 command line, create headers.h
like this:
cl /P headers.cpp /Fiheaders.h
The /P option is documented here.
You can then compile test.cpp
in the usual way:
cl test.cpp
(Obviously in this case the program won't link because we haven't defined myFunction, but it compiles perfectly happily.)
With a bit of fiddling around it shouldn't be too hard to automate the building of headers.h
rather than doing it from the command line.
In some C++ compilers the preprocessor is actually a separate executable (this was the traditional model) but if not there should still be an option to just run the preprocessor without invoking the compiler.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With