Name conflict with windows.h define

W

Whywhat

Hi!

I have a name conflict between my class and windows.h header. The
problem is because of windows.h contains GetMessage macro and my class
a method with the same name. Thus the macro replaces my method
declaration in the main module which contains these lines:

#include <windows.h>
#include "myclass.h"

But in myclass.cpp file windows.h is not included. So I have GetMessage
method compiled and GetMessageA referenced in the main module. Of
course, it causes an 'unresolved external symbol' linker error.

Is there any "good" solution to avoid these uncomfortable error.
Anything instead of renaming (this seems to be the best now for me) my
method, including windows.h into myclass.cpp or so. Can I in some way
disable macro and enable it again?

I guess, smth like that will work, probably:

// myclass.h
#pragma once

#ifdef GetMessage
# undef GetMessage
# define GET_MESSAGE_WAS_DEFINED
#endif

class MyClass
{
...
};

#ifdef GET_MESSAGE_WAS_DEFINED
# undef GET_MESSAGE_WAS_DEFINED
# ifdef _UNICODE
# define GetMessage GetMessageA
# else
# define GetMessage GetMessageW
# endif
#endif

But still, I don't like this solution. It is still is not flexible and
portable (especially if real GetMessage macro definition will change)

And why the hell this global preprocessor definition conflicts with my
class method!!!
I don't like it at all.

Thanks, for any advice about solving the problem.
 
B

benben

And why the hell this global preprocessor definition conflicts with my
class method!!!
I don't like it at all.

I guess no one likes it. Here are some possibilities in addition to what
you have posted:

1. Change your naming style. Don't use GetMessage, instead, use
getMessage, or get_message or (my personal favorite) get_msg.

2. Don't include <windows.h> or other notorious headers. This may be
overkilling but I used to put the header only in a source file called
PAL.cpp (Platform Abstraction Layer) and put necessary declarations to
wrapper functions in PAL.hpp. This way you not only filters the nasty
macros but also improves portability.

3. Include the header only after your GetMessage. It might seem
unnatural but it should do the trick. But if your GetMessage uses
anything from <windows.h> then you may have to manually forward declare
all those.

4. Provide your wrapper header that does all the macro tricks. E.g.

// windows_wrapped.h

#include <windows.h>

#if (GetMessage == GetMessageA)
#undef GetMessage

BOOL GetMessage(LPMSG msg, HWND hwnd,
UINT m, UINT n){
return ::GetMessageA(msg, hwnd, m, n);}

#endif

#if (GetMessage == GetMessageA)
#undef GetMessage

inline BOOL GetMessage(LPMSG msg, HWND hwnd,
UINT m, UINT n){
return ::GetMessageA(msg, hwnd, m, n);}

#endif

#if (GetMessage == GetMessageW)
#undef GetMessage
inline BOOL GetMessage(LPMSG msg, HWND hwnd,
UINT m, UINT n){
return ::GetMessageW(msg, hwnd, m, n);}

#endif

This way the symbol you will have to deal with is no longer a
preprocessor macro so namespace rules apply.

Regards,
Ben
 
Z

zeior

You can solve the problem by including windows.h in the header, so that
the actual name will be GetMessageA/GetMessageW, also in the
compilation unit. Another way, which is already suggested is to change
your name to something like GetMsg, RetrieveMsg, RetrieveMessage or
something like that.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top