Сведения о вопросе

Martincow

19:42, 13th August, 2020

Теги

c++    

C++ компоновщик неразрешенных внешних символов

Просмотров: 411   Ответов: 4

Я создаю приложение на основе некоторых устаревших сторонних библиотек и испытываю проблемы с этапом компоновки. Я пытаюсь компилировать с помощью 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-это:

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, поэтому я надеюсь, что это просто какое-то невежество с моей стороны. Есть идеи, как их решить?



  Сведения об ответе

pumpa

19:46, 21st August, 2020

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

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


  Сведения об ответе

crush

03:40, 4th August, 2020

Проверьте это на MSDN :

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

Отмечать: "... так что компоновщик будет использовать LIBCMT.lib для разрешения внешних символов"

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

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

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

Старый скул, но он работал на меня.

Янв


  Сведения об ответе

COOL

18:23, 6th August, 2020

Если вы все еще хотите получить проект для компиляции с помощью 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" . Это означает, что объектный файл был скомпилирован со статической многопоточной отладкой c во время выполнения.

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


  Сведения об ответе

$DOLLAR

00:51, 18th August, 2020

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

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться