GetObject - GetObjectA链接器错误

时间:2010-07-11 16:47:30

标签: c++ visual-c++

在我的项目中,我有一个名为GetObject的函数,它包含在我的静态库中的一个类中。当我在另一个使用我的库的项目中调用该函数时,我收到了这个错误:

错误1错误LNK2019:未解析的外部符号“public:class hamur :: HamurObject * __thiscall hamur :: HamurWorld :: GetObjectA(class std :: basic_string,class std :: allocator> const&)”(?GetObjectA @ HamurWorld @ hamur @@ QAEPAVHamurObject @ 2 @ ABV?$ basic_string @ DU?$ char_traits @ D @ std @@ V?$ allocator @ D @ 2 @@ std @@@ Z)在函数“public:virtual void __thiscall”中引用MainState :: Draw(void)“(?Draw @ MainState @@ UAEXXZ)MainState.obj

据我所知,问题是GetObject是“windows.h”中的预处理器定义,它变成了GetObjectA。

我的问题是:

我从来没有在我的任何文件中添加“windows.h”标头。我正在使用SDL,Fmod,OpenGL。我发现它来自SDL_opengl.h

我试过用:

#ifdef GetObject
#undef GetObject
#endif

它成功了。这是一个好的或唯一可行的解​​决方案吗?我正在尝试实现一个应该在多平台上工作的库,但我没有测试为Windows以外的任何平台编译它,所以我现在非常担心移植。在移植事情变得更糟之前得到一些建议会非常好......

我目前的环境是Windows Xp - Visual Studio 2008。

先谢谢

2 个答案:

答案 0 :(得分:5)

这是一个很好的例子,说明为什么使用没有任何类型的库限定(GetObject而不是WINDOWS_GetObject)的宏实际上是非常愚蠢的,并且是灾难的秘诀。所以,谢谢你的例子。

这在其他平台上应该不是问题(在UNIX的实现中发现这种宏的废话很少见)。您真正应该担心的是,如果您在Windows上更改标题包含顺序并且在包含包含#undef的标题后使用SDL OpenGL的功能,您的项目是否仍然有效。您可能希望在头文件的末尾恢复GetObject的值。虽然我怀疑它在UNIX上会出现问题,但我建议将其设为仅限Windows:

// Your header file

#ifndef YOURHEADER_INCLUSION_GUARD
#define YOURHEADER_INCLUSION_GUARD

// ... your various includes ...

#ifdef OS_WINDOWS
#    ifdef GetObject
#        define MYPROJECT_MACRO_GETOBJECT_WAS_DEFINED
#    endif
#    undef GetObject
#endif

// ... the rest of your header ...

#ifdef OS_WINDOWS
#    if defined(MYPROJECT_MACRO_GETOBJECT_WAS_DEFINED)
#        undef MYPROJECT_MACRO_GETOBJECT_WAS_DEFINED
#        define GetObject GetObjectA
#    endif
#endif

#endif // End header inclusion guard

在你的源文件中,你可以对这些宏稍微有点松懈,因为你可以控制源文件中的头包含顺序,而其他任何人都不会包含你的源文件。

答案 1 :(得分:3)

它将解决Windows的问题,但是我建议将您的方法重命名为代码库中比GetObject更具描述性的内容,因为您可能会发现与SetObject等类似的冲突。此外,您实际上可能希望在以下位置使用这些Win32 API。有一点,#undef会让你更难处理。