Неразрешенный внешний символ при использовании dllexport и имени конкретной функции

РЕДАКТИРОВАТЬ

Чтобы обойти проблему, я добавил следующее (начало) заголовочного файла:

#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

Я создаю C ++ DLL (используя Visual Studio 2008) из кода, подобного следующему:

Заголовочный файл:

#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:

TestBaseClass::TestBaseClass()
{
}

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

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

Когда я иду на компиляцию DLL, я получаю ошибку компоновщика:

ошибка LNK2001: неразрешенный внешний символ «public: virtual char *
__thiscall TestDerivedClass :: GetMessageA (void) «(? GetMessageA @ TestDerivedClass @@ UAEPADXZ)

Если я изменяю каждый экземпляр «GetMessage» на что-то другое (например, «TestFunc»), я не получаю ошибку компоновщика.

Основной вопрос: Почему я не могу использовать «GetMessage» в качестве имени моей функции?

Вторичный вопрос: Есть ли способ устранить ошибку компоновщика и сохранить «GetMessage» в моем классе, как определено в настоящее время?

2

Решение

Это связано с причудой в заголовках Windows. Когда ты #include <windows.h>, Это #defineсимвол GetMessage либо GetMessageA или же GetMessageWв зависимости от того, включена ли поддержка Unicode (более конкретно, если UNICODE макрос определен) — см. Юникод в Windows API а также Соглашения для функциональных прототипов для получения дополнительной информации об этом.

Чтобы обойти это, у вас есть несколько вариантов:

  • Не включайте заголовки Windows
  • Определить макрос NOMSG прежде чем включать <windows.h> — это подавит объявления различных связанных с сообщениями функций и макросов
  • #undef GetMessage до вашего определения класса
  • Переименуйте свою функцию в другое
4

Другие решения

Это довольно стандартная потеря препроцессора. Ваш идентификатор получает удар по макросу. Он живет в заголовках Windows, переименовывает функцию winapi GetMessage () в GetMessageA или GetMessageW, в зависимости от того, определен ли UNICODE.

Выберите другое имя или используйте #undef GetMessage

5

По вопросам рекламы [email protected]