testuser2 / hadesmem

Automatically exported from code.google.com/p/hadesmem
0 stars 0 forks source link

Annoying GetMessage() problem #9

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
I have a class with a function called GetMessage(). Compiles fine. As soon as i 
include Hades (HadesMemory\Memory.hpp), I get the following error:

Error   1   error C2039: 'GetMessageW' : is not a member of 'MyClass'

I remove the include line, and it compiles again.

Original issue reported on code.google.com by aidan.b....@gmail.com on 25 Jun 2011 at 9:26

GoogleCodeExporter commented 9 years ago
HadesMem includes <Windows.h>, and the Windows headers do stuff like the 
following:
#ifdef UNICODE
#define GetMessage GetMessageW
#else
#define GetMessage GetMessageA
#endif

Etc.

The problem is not in HadesMem, but rather that the Windows headers kinda trump 
all over the global scope with the preprocessor.

Unfortunately it's not something I can really fix, as it's not a problem in my 
library, it's a problem with the Windows SDK.

The easiest workaround is simply to avoid using the same API names that the 
Windows SDK does, but if you can't or don't want to do that, then you should be 
able to tell your compiler what you REALLY mean by using parentheses.

E.g.
SomeClassInstance.GetMessage(); // May cause problems
(SomeClassInstance.GetMessage)(); // 'Force' compiler to understand what you 
mean

Note: I haven't tested the above solution, I usually just avoid duplicating the 
Windows API names. It SHOULD work, however then you have the problem that user 
code is forced to do this... It's quite an annoying situation, so my 
recommendation is to simply change the API name.

Sorry I can't be of more help.

Original comment by raptorfactor@raptorfactor.com on 26 Jun 2011 at 6:44

GoogleCodeExporter commented 9 years ago
you can solve like this:

#ifdef GetMessage
#undef GetMessage
// add your codes like Someone::GetMessage here
#define GetMessage
#endif

Original comment by evenson...@gmail.com on 24 Nov 2012 at 1:37

GoogleCodeExporter commented 9 years ago
Not really, because you're not preserving the original macro.

Consider the following:
#define FOO bar

Your solution effectively redefines FOO like this:
#define FOO

Which is obviously broken.

You need to use compiler pragmas to push the state of the macro at the point 
where you undef it, then pop it afterwords. Most compilers do have unofficial 
extensions to allow this.

Original comment by raptorfactor@raptorfactor.com on 24 Nov 2012 at 1:39

GoogleCodeExporter commented 9 years ago
#ifdef WIN32
#pragma push_macro("GetMessage")
#undef GetMessage
#endif

// use GetMessage here

#ifdef WIN32
#pragma pop_macro("GetMessage")
#endif

Original comment by shoog...@gmail.com on 25 Jun 2013 at 8:56

GoogleCodeExporter commented 9 years ago
What about when external callers want to call your GetMessage function and they 
have their headers like so:

#include <windows.h>
#include <your_lib_which_includes_getmessage_func.h>

YourNamespace::GetMessage(); // Error here! GetMessage gets changed to 
GetMessageW

They can of course do this:
(YourNamespace::GetMessage)();

But that's hardly a very elegant solution (though at least it's more elegant 
than pragma hackery.

For code that other people consume, the best solution is to simply not use the 
same names as the Windows SDK. Yes, there are ways around it, but it's better 
to just not do it in the first place.

Original comment by raptorfactor@raptorfactor.com on 25 Jun 2013 at 9:34

GoogleCodeExporter commented 9 years ago
I'll also point out that the above syntax for preventing the macro substitution 
does not work all the time, which is why Boost has monstrosities like 
BOOST_PREVENT_MACRO_SUBSTITUTION.

http://www.boost.org/doc/libs/1_53_0/libs/config/doc/html/boost_config/boost_mac
ro_reference.html#boost_config.boost_macro_reference.boost_helper_macros

It sucks, but just pick a different name for your function. Your library's 
users and the future maintainers of your code will thank you for it.

Original comment by raptorfactor@raptorfactor.com on 25 Jun 2013 at 9:37