Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need a header file that undefs all defines in windows.h

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).
like image 278
defube Avatar asked Jul 14 '12 22:07

defube


1 Answers

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.

like image 68
Harry Johnston Avatar answered Nov 19 '22 09:11

Harry Johnston