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

次のようなコードから(Visual Studio 2008を使用して)C++DLLを作成しています。

ヘッダーファイル:

#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」を保持する方法はありますか?

4

2 に答える 2

5

これはかなり標準的なプリプロセッサの損失です。あなたの識別子はマクロによって破壊されています。これは Windows ヘッダー内に存在し、UNICODE が定義されているかどうかに応じて、winapi GetMessage() 関数の名前を GetMessageA または GetMessageW に変更します。

別の名前を選択するか、#undef GetMessage を使用してください

于 2013-01-14T16:55:18.773 に答える
5

これは、Windows ヘッダーの癖によるものです。の場合は#include <windows.h>、Unicode サポートが有効になっているかどうかに応じて (より具体的には、マクロが定義されている場合) または のいずれかのシンボルになります。詳細については、#defineWindows API の Unicode関数プロトタイプの規則を参照してください。GetMessageGetMessageAGetMessageWUNICODE

これを回避するには、いくつかのオプションがあります。

  • Windows ヘッダーを含めないでください
  • NOMSGインクルードの前にマクロを定義します<windows.h>-- これにより、さまざまなメッセージ関連の関数とマクロの宣言が抑制されます
  • #undef GetMessageクラス定義の前に
  • 関数の名前を別の名前に変更します
于 2013-01-14T16:57:04.593 に答える