3

编辑

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

#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:未解析的外部符号“公共:虚拟字符 * __thiscall TestDerivedClass::GetMessageA(void)”(?GetMessageA@TestDerivedClass@@UAEPADXZ)

如果我将“GetMessage”的每个实例更改为其他内容(例如“TestFunc”),我不会收到链接器错误。

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

第二个问题:有没有办法解决链接器错误,并按照当前定义在我的班级中保留“GetMessage”?

4

2 回答 2

5

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

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

于 2013-01-14T16:55:18.773 回答
5

这是由于 Windows 标头中的一个怪癖。当 you 时#include <windows.h>,它是or 或#define的符号,具体取决于您是否启用了 Unicode 支持(更具体地说,如果定义了宏)——有关更多信息,请参阅Windows API 中的 UnicodeFunction Prototypes 的约定。GetMessageGetMessageAGetMessageWUNICODE

要解决此问题,您有几个选择:

  • 不要包含 Windows 标头
  • NOMSG在 include 之前定义宏<windows.h>——这将抑制各种与消息相关的函数和宏的声明
  • #undef GetMessage在你的班级定义之前
  • 将您的功能重命名为其他名称
于 2013-01-14T16:57:04.593 回答