在我的项目中,我有一个名为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。
先谢谢
答案 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会让你更难处理。