C ++ компоновщик неразрешенных внешних символов - PullRequest
1 голос
/ 22 августа 2008

Я создаю приложение для некоторых устаревших сторонних библиотек, и у меня возникают проблемы с этапом компоновки. Я пытаюсь скомпилировать с помощью Visual Studio 9. Моя команда компиляции:

cl -DNT40 -DPOMDLL -DCRTAPI1=_cdecl
-DCRTAPI2=cdecl -D_WIN32 -DWIN32 -DWIN32_LEAN_AND_MEAN -DWNT -DBYPASS_FLEX -D_INTEL=1 -DIPLIB=none -I. -I"D:\src\include" -I"C:\Program Files\Microsoft Visual Studio
9.0\VC\include" -c -nologo -EHsc -W1 -Ox -Oy- -MD mymain.c

Код компилируется чисто. Команда ссылки:

link -debug -nologo -machine:IX86
-verbose:lib -subsystem:console mymain.obj wsock32.lib advapi32.lib
msvcrt.lib oldnames.lib kernel32.lib
winmm.lib [snip large list of
dependencies] D:\src\lib\app_main.obj
-out:mymain.exe

Я получаю следующие ошибки:

app_main.obj : error LNK2019:
unresolved external symbol
"_\_declspec(dllimport) public: void
__thiscall std::locale::facet::_Register(void)"
(__imp_?_Register@facet@locale@std@@QAEXXZ)
referenced in function "class
std::ctype<char> const & __cdecl
std::use_facet<class std::ctype<char>
(class std::locale const &)" (??$use_facet@V?$ctype@D@std@@@std@@YAABV?$ctype@D@0@ABVlocale@0@@Z)

app_main.obj : error LNK2019:
unresolved external symbol
"__declspec(dllimport)  public: static
unsigned int __cdecl
std::ctype<char>::_Getcat(class
std::locale::facet const * *)"
(__imp_?_Getcat@?$ctype@D@std@@SAIPAPBVfacet@locale@2@@Z)
referenced in function "class
std::ctype<char> const & __cdecl
std::use_facet<class std::ctype<char>
(class std::locale const &)" (??$use_facet@V?$ctype@D@std@@@std@@YAABV?$ctype@D@0@ABVlocale@0@@Z)

app_main.obj : error LNK2019:
unresolved external symbol
"__declspec(dllimport)  public: static
unsigned int __cdecl
std::ctype<unsigned
short>::_Getcat(class
std::locale::facet const * *)"
(__imp_?_Getcat@?$ctype@G@std@@SAIPAPBVfacet@locale@2@@Z)
referenced in function "class
std::ctype<unsigned short> const &
__cdecl std::use_facet<class std::ctype<unsigned short> >(class
std::locale const &)"
(??$use_facet@V?$ctype@G@std@@@std@@YAABV?$ctype@G@0@ABVlocale@0@@Z)

mymain.exe : fatal error LNK1120: 3
unresolved externals

Обратите внимание, что эти ошибки происходят из устаревшего кода, а не из моего кода - app_main.obj является частью устаревшего кода, а mymain.c является моим источником. Я провел некоторый поиск по всему, и то, что я прочитал, говорит о том, что этот тип ошибки вызван несоответствием переключателя -MD между моим кодом и библиотекой, на которую я ссылаюсь. Поскольку я имею дело с устаревшим кодом, решение должно исходить из моей среды. Прошло много времени с тех пор, как я работал с C ++, и даже дольше, так как я использовал Visual Studio, поэтому я надеюсь, что это просто некоторое невежество с моей стороны. Любые идеи о том, как решить эти проблемы?

Ответы [ 4 ]

4 голосов
/ 22 августа 2008

Это ссылки на стандартные библиотеки. Убедитесь, что все библиотеки (включая стандартную библиотеку) используют одинаковую связь . Например. вы не можете ссылаться статически при динамической компоновке стандартной библиотеки. То же самое касается используемой модели потоков. Обратите особое внимание на то, чтобы вы и сторонняя библиотека использовали одинаковые параметры связи.

Это может быть настоящей болью в * ss.

2 голосов
/ 05 сентября 2008

Если вы все еще хотите получить проект для компиляции с использованием VS2008 (или в будущем), я могу предложить использовать двоичный редактор для просмотра рассматриваемого объектного файла mainapp.obj .

Вот пример из моего небольшого проекта.

zdbException.obj содержит следующую выдержку

DEFAULTLIB:"libc
pmtd" /DEFAULTLI
B:"uuid.lib" /DE
FAULTLIB:"uuid.l
ib" /include:?id
@?$num_put@DV?$o
streambuf_iterat
or@DU?$char_trai
ts@D@std@@@std@@
@std@@2V0locale@
2@A /include:?id
@?$numpunct@D@st
d@@2V0locale@2@A
 /DEFAULTLIB:"LI
BCMTD" /DEFAULTL
IB:"OLDNAMES" /E
DITANDCONTINUE 

Обратите внимание на запись / DEFAULTLIB: "LIBCMTD" . Это указывает на то, что объектный файл был скомпилирован со статической многопоточной отладкой во время выполнения.

Существует также вероятность того, что функции, на которые есть ссылки в obj, устарели в стандартной библиотеке времени выполнения, поставляемой с VS2008.

2 голосов
/ 25 августа 2008

Отметьте это на MSDN :

  • / MD Заставляет ваше приложение использовать многопоточную и DLL-специфичную версию библиотеки времени выполнения.
  • / MT Заставляет ваше приложение использовать многопоточную статическую версию библиотеки времени выполнения.

Примечание: «... чтобы компоновщик использовал LIBCMT.lib для разрешения внешних символов»

Так что вам понадобится другой набор библиотек.

Как я узнал, на какие библиотеки ссылаться:

  1. Найдите конфигурацию, которая делает ссылку, и добавьте / подробный параметр.
  2. Передать вывод в текстовый файл.
  3. Попробуйте конфигурацию, которую не связывает.
  4. Посмотрите в подробном выводе из шага 2 символы, которые не были разрешены ("_declspec (dllimport) public: void thiscall std :: locale :: facet :: Register (void)" в вашем случае) и найдите используемые библиотеки .
  5. Добавить эти библиотеки в список библиотек, на которые вы ссылаетесь.

Старый skool, но он работал для меня.

Jan

0 голосов
/ 25 августа 2008

После попытки заставить этот материал скомпилироваться под VS 2008, я попробовал более ранние версии VS - 2005, работали с предупреждениями, а 2003 просто работал. Я дважды проверил связи и не смог найти никаких проблем, так что я просто не мог их найти, или это не было проблемой.

Так что повторюсь, понижение до VS 2003 исправило его.

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