GetObject - ошибка компоновщика GetObjectA - PullRequest
4 голосов
/ 11 июля 2010

В моем проекте есть функция GetObject, которая помещена в один из моих классов в моей статической библиотеке.Когда я вызываю функцию в другом проекте, который использует мою библиотеку, я получаю эту ошибку:

Ошибка 1, ошибка LNK2019: неразрешенный внешний символ "public: class hamur :: HamurObject * __thiscall hamur :: HamurWorld :: GetObjectA(класс std :: basic_string, класс 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 ]

5 голосов
/ 11 июля 2010

Это прекрасный пример того, почему использование макросов без какой-либо квалификации библиотеки (GetObject вместо WINDOWS_GetObject) действительно глупо и является причиной катастрофы. Итак, спасибо за пример.

Это не должно быть проблемой на других платформах (нахождение такого рода бессмысленных макросов довольно редко встречается в реализациях UNIX). Что вас действительно должно волновать, так это то, будет ли ваш проект работать, если вы измените порядок включения заголовка в Windows и используете функцию SDL OpenGL после того, как вы включите заголовок, который содержит #undef. Возможно, вы захотите восстановить значение 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

В вашем исходном файле вы можете позволить себе быть немного неаккуратным с макросами, так как вы можете контролировать порядок включения заголовка в вашем исходном файле, и никто больше не собирается включать ваш исходный файл.

3 голосов
/ 11 июля 2010

Это решит проблему для Windows, однако я рекомендую переименовать ваш метод в нечто более описательное, чем GetObject в вашей кодовой базе, так как вы можете столкнуться с подобными конфликтами с SetObject и т. Д. Кроме того, вы можете использовать эти Win32 API в некоторый момент, и #undef сделает это более хитрым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...