3

EDIT

To get around the problem, I added the following to the (beginning of the) header file:

#ifdef GetMessage
#undef GetMessage
static inline BOOL GetMessage(
LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax
) {
#if UNICODE
return ::GetMessageW(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
#else
return ::GetMessageA(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
#endif
}
#endif

I'm creating a C++ DLL (using Visual Studio 2008) from code like the following:

Header File:

#include <windows.h> // Edit: This is the culprit.
class __declspec(dllexport) TestBaseClass
{
protected:
   char m_Message[512];
public:
   TestBaseClass();
   virtual char* GetMessage(void) = 0;
};

class __declspec(dllexport) TestDerivedClass : public TestBaseClass
{
public:
   TestDerivedClass();
   virtual char* GetMessage(void);
};

CPP File:

TestBaseClass::TestBaseClass()
{
}

TestDerivedClass::TestDerivedClass() : TestBaseClass()
{
}

char* TestDerivedClass::GetMessage(void)
{
   sprintf(m_Message, "This is a Message");
   return m_Message;
}

When I go to compile the DLL, I get a linker error:

error LNK2001: unresolved external symbol "public: virtual char * __thiscall TestDerivedClass::GetMessageA(void)" (?GetMessageA@TestDerivedClass@@UAEPADXZ)

If I change every instance of "GetMessage" to something else (e.g. "TestFunc"), I do not get the linker error.

Primary Question: Why can't I use "GetMessage" as my function name?

Secondary Question: Is there a way to resolve the linker error, and keep "GetMessage" in my class, as currently defined?

TreDubZedd
  • 2,571
  • 1
  • 15
  • 20

2 Answers2

5

This is pretty standard preprocessor lossage. Your identifier is getting whacked by a macro. It lives inside the Windows headers, it renames the winapi GetMessage() function to either GetMessageA or GetMessageW, depending on whether UNICODE defined.

Pick another name or use #undef GetMessage

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
5

It's due to a quirk in the Windows headers. When you #include <windows.h>, it #defines the symbol GetMessage to either GetMessageA or GetMessageW, depending on whether or not you have Unicode support enabled (more specifically, if the UNICODE macro is defined) -- see Unicode in the Windows API and Conventions for Function Prototypes for more info on that.

To work around this, you have a few options:

  • Don't include the Windows headers
  • Define the macro NOMSG before include <windows.h> -- this will suppress the declarations of various message-related functions and macros
  • #undef GetMessage before your class definition
  • Rename your function to something else
Community
  • 1
  • 1
Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589