使用dllexport和特定函数名称时未解析的外部符号

Unresolved External Symbol when using dllexport and specific function name

本文关键字:符号 外部 dllexport 函数 使用      更新时间:2023-10-16

编辑

为了解决这个问题,我在头文件的开头添加了以下内容:

#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:虚拟字符*__thiscall TestDerivedClass::GetMessageA(void("(?GetMessageA@TestDerivedClass@@UAEPADXZ(

如果我将"GetMessage"的每个实例都更改为其他实例(例如"TestFunc"(,则不会得到链接器错误。

主要问题:为什么我不能使用"GetMessage"作为函数名?

次要问题:有没有办法解决链接器错误,并将"GetMessage"保留在我的类中,如当前定义的那样?

这是由于Windows标头中的一个怪癖。当您使用#include <windows.h>时,它#define将符号GetMessage转换为GetMessageAGetMessageW,具体取决于您是否启用了Unicode支持(更具体地说,如果定义了UNICODE宏(--有关更多信息,请参阅Windows API中的Unicode和函数原型惯例。

要解决这个问题,你有几个选择:

  • 不包括Windows标头
  • 在包含<windows.h>之前定义宏NOMSG——这将抑制各种与消息相关的函数和宏的声明
  • 类定义前的#undef GetMessage
  • 将您的函数重命名为其他函数

这是相当标准的预处理器损失。您的标识符被宏破坏了。它位于Windows标头中,它将winapi GetMessage((函数重命名为GetMessageA或GetMessageW,具体取决于是否定义了UNICODE。

选择其他名称或使用#undef GetMessage

相关文章: