Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GetObject - GetObjectA linker error

Tags:

c++

visual-c++

In my project I have a function named GetObject that is wrapped in one of my classes in my static library. When I call the function in another project that is using my library, I got this error:

Error 1 error LNK2019: unresolved external symbol "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) referenced in function "public: virtual void __thiscall MainState::Draw(void)" (?Draw@MainState@@UAEXXZ) MainState.obj

As I understand problem is GetObject is a preprocessor definition in "windows.h" and it becomes GetObjectA instead.

My question is:

I have never added "windows.h" header to any of my files. I am using SDL, Fmod, OpenGL. I have found that it comes from SDL_opengl.h

I have tried to use:

#ifdef GetObject
#undef GetObject
#endif

It worked out. Is it a good or only possible solution? I am trying to implement a library that should work in multi-platforms but I didn't test to compile it for any platform other than Windows, so I am now quite worried about porting. It would be very nice to have some advice before the things got worse for porting...

My current environment is Windows Xp - Visual Studio 2008.

Thanks in Advance

like image 277
chaosmaker Avatar asked Jan 21 '23 19:01

chaosmaker


1 Answers

This is a perfect example of why using macros without any sort of library qualification (GetObject instead of WINDOWS_GetObject) is really stupid and a recipe for disaster. So, thanks for the example.

This should not be a problem on other platforms (finding this kind of macro nonsense is quite rare on implementations of UNIX). What you really should worry about is whether your project will still work if you change the header inclusion order on Windows and use a feature of SDL OpenGL after you include your header that contains the #undef. You might want to restore the value of GetObject at the end of your header file. Although I doubt it would be a problem on UNIX, I would suggest making it Windows-only:

// 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

In your source file, you can afford to be a little sloppier with the macros, since you can control the header inclusion order in your source file and no one else is going to include your source file.

like image 184
Michael Aaron Safyan Avatar answered Jan 24 '23 07:01

Michael Aaron Safyan