Search code examples
c++dlldllexport

Unresolved External Symbol when using dllexport and specific function name


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?


Solution

  • 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