Ошибка ссылки: xxx уже определен в *****. LIB :: Что именно не так? - PullRequest
5 голосов
/ 28 апреля 2010

Проблема:

Я пытаюсь использовать библиотеку с именем DCMTK , которая использует некоторые другие внешние библиотеки (zlib, libtiff, libpng, libxml2, libiconv). Я загрузил эти внешние библиотеки (файлы * .LIB & * .h) с того же сайта. Теперь, когда я компилирую библиотеку DCMTK, я получаю ошибки ссылок (793 ошибки), например:

Error   2   error LNK2005: __encode_pointer already defined in MSVCRTD.lib(MSVCR90D.dll)    LIBCMTD.lib dcmmkdir 
Error   3   error LNK2005: __decode_pointer already defined in MSVCRTD.lib(MSVCR90D.dll)    LIBCMTD.lib dcmmkdir 
Error   4   error LNK2005: __CrtSetCheckCount already defined in MSVCRTD.lib(MSVCR90D.dll)  LIBCMTD.lib dcmmkdir 
Error   5   error LNK2005: __invoke_watson already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir 
Error   6   error LNK2005: __errno already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir 
Error   7   error LNK2005: __configthreadlocale already defined in MSVCRTD.lib(MSVCR90D.dll)    LIBCMTD.lib dcmmkdir 
Error   8   error LNK2005: _exit already defined in MSVCRTD.lib(MSVCR90D.dll)   LIBCMTD.lib dcmmkdir 

Документация:

Это, похоже, распространенная ошибка для этой библиотеки, поэтому у них есть запись часто задаваемых вопросов, посвященная этой проблеме, которая (http://forum.dcmtk.org/viewtopic.php?t=35) говорит:

  • Проблема в том, что компоновщик пытается объединить разных, несовместимые версии Visual C ++ библиотека времени выполнения в единый двоичный файл.
  • Это происходит, когда не все части вашего проекта и библиотеки вы ссылка на генерируется с те же параметры генерации кода в Visual C ++.
  • Не используйте обходной путь / NODEFAULTLIB, потому что странное программное обеспечение возможны сбои. Решить проблему!

  • DCMTK по умолчанию компилируется с "Многопоточностью" или "Многопоточностью" Отладка "вариант генерации кода ( последний для режима отладки).

  • Либо измените настройки проекта всего вашего кода, чтобы использовать этот код Варианты генерации,
  • или измените генерацию кода для всех модулей DCMTK и перекомпилируйте.
  • Пользователи MFC, будьте осторожны: DCMTK должен быть скомпилирован с помощью «Многопоточной DLL» или Настройки «Многопоточная отладка DLL», если Вы хотите связать библиотеки в Приложение MFC.

Решение той же проблемы для других:

Огромное количество проблем с компоновщиком только при сборке релиза говорит:

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

С технической точки зрения вы, кажется, связывание проектов, построенных с разными C Run Time library настройки, один с "Многопоточным", еще один с "Многопоточной отладкой". регулировать настройки для всех проектов использовать тот же вкус библиотека и вопрос должен уйти

Вопросы:

До сих пор я думал, что искажение имен - это единственная проблема, которая может привести к ошибкам компоновки, если она не стандартизирована. Просто теперь я знал, что есть и другие вещи, которые могут вызвать тот же эффект.

  1. Что происходит с «Режимом отладки» (Многопоточная отладка) и «Режимом выпуска» (Многопоточность)? Что именно точно происходит под капотом? Почему точно эта вещь вызывает ошибку компоновки?

  2. Интересно, есть ли что-то под названием «Однопоточная отладка» и «Однопоточная», которая снова вызывает то же самое?

  3. Документация говорит о «параметрах генерации кода». Какие варианты генерации кода? ЧТО они?

  4. Документация специально предупреждает нас не использовать обходной путь / NODEFAULTLIB. (пример / NODEFAULTLIB: msvcrt). Зачем? Как бы я вызвал проблемы? что именно это?

  5. Пожалуйста, объясните последний пункт в документации для пользователей MFC. Потому что я собираюсь использовать MFC позже в этом проекте. Объясните, почему мы должны это делать? Какие неприятности это может вызвать, если я этого не сделаю.
  6. Что-нибудь еще, что вы хотели бы упомянуть? Я имею в виду похожие ошибки. Я очень заинтересован в линкере и его проблемах. Так что, если есть какие-либо подобные вещи, вы можете упомянуть их или как минимум несколько ключевых слов.

Ответы [ 3 ]

8 голосов
/ 28 апреля 2010

Что происходит с «Режимом отладки» (Многопоточная отладка) и «Режимом выпуска» (Многопоточность)?Что именно происходит под капотом?Почему именно это вызывает ошибку компоновки?

Компоновщик перетаскивает в библиотеки по нескольким причинам.Самым простым является то, что библиотека указана в командной строке компоновщика или в файле ответов компоновщика в командной строке компоновщика.Но любые объектные файлы, независимо от того, скомпилированы ли они в вашем проекте или упакованы в библиотеку, также могут содержать опций компоновщика , включая запрос на связывание определенных библиотек. Фактически, компилятор Visual C ++ автоматически встраивает такие опции компоновщика, соответствующие проекту.Опции, которые вы используете при компиляции.

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

Интересно, есть личто-то под названием «Однопоточная отладка» и «Однопоточная», что снова вызывает ту же самую вещь.

Раньше было, но последние несколько версий Visual C ++ имели только многопоточную совместимостьбиблиотеки.

Документация говорит кое-что о "Опции генерации кода".Какие варианты генерации кода?WTH они?

Загляните в параметры вашего проекта .

Документация специально предупреждает нас не использовать обходной путь / NODEFAULTLIB.(пример / NODEFAULTLIB: msvcrt).Зачем?Как бы я вызвал проблемы?что именно это?

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

Пожалуйста, объясните последний пункт в документации для пользователей MFC.Потому что я собираюсь использовать MFC позже в этом проекте.Объясните, почему мы должны это делать?Какие неприятности это может вызвать, если я не буду.Что-нибудь еще, что вы хотели бы упомянуть?Я имею в виду похожие ошибки.Я очень заинтересован в линкере и его проблемах.Таким образом, если есть какие-либо подобные вещи, вы можете упомянуть их или несколько ключевых слов по крайней мере.

Приложения MFC и библиотека MFC должны использовать одни и те же функции управления памятью, чтобы можно было освободить память, выделенную MFC.по заявке и наоборот.Дескрипторы FILE и другие ресурсы также являются общими.DLL-библиотеки MFC уже скомпилированы для использования CRT в DLL, и для того, чтобы иметь возможность совместно использовать ресурсы, вам необходимо использовать ту же CRT, что также означает использование DLL.

0 голосов
/ 28 апреля 2010

Вам необходимо настроить свойства проекта таким образом, чтобы ссылки на сборку отладки с помощью отладочной сборки DCMTK и ссылки на сборку выпуска с сборкой выпуска DCMTK.

Это то, что вам нужно сделать. Ниже приведены объяснения некоторых других случайных вещей, о которых вы спрашивали.

В старых версиях Visual Studio помимо многопоточных библиотек (версии выпуска и отладки) использовались однопоточные библиотеки (версии выпуска и отладки). Для вашего проекта вы можете сделать вид, что однопоточных библиотек никогда не было.

Если вы экспериментируете со случайными способами заставить компоновщик замолчать и оставить проблемы, которые будут обнаружены вашими клиентами, а не вами, вы можете обнаружить, что опция / NODEFAULTLIB сделает это. Создатели библиотеки DCMTK предупреждают вас не делать этого, потому что некоторые другие люди делали то же самое в прошлом.

0 голосов
/ 28 апреля 2010

Что происходит с «режимом отладки» (многопоточная отладка) и «режимом выпуска» (многопоточность)? Что именно происходит под капотом? Почему именно эта вещь вызывает ошибку компоновки?

Это разные версии библиотеки времени выполнения C. Вы можете статически связываться с библиотекой времени выполнения в режиме отладки и выпуска. В опциях генерации кода (упомянутых ниже) это будут «Многопоточная отладка» и «Многопоточная». Параметры «Многопоточная отладочная DLL» и «Многопоточная DLL» динамически связываются со средой выполнения C. При динамической привязке к среде выполнения вам также потребуется отправить установщик, настроенный для установки распространяемого пакета VC, который содержит соответствующие библиотеки времени выполнения для вашей версии Visual C ++.

Статическая ссылка на среду выполнения C обычно не одобряется, даже Microsoft :

В дополнение ко всем методам описанный выше распределения Visual C ++ библиотеки DLL, есть последний вариант для построения вашего приложение, которое не требует вас распространять библиотеки DLL. Тем не менее, это опция работает только для нативного кода (не поддерживается с / clr) и оставляет своих клиентов серьезно уязвимы для любых дыр в безопасности а также добавляет значительное бремя на самостоятельно патчить все клиентские системы должна ли быть обнаружена уязвимость в любом из библиотек. Эта опция для статически ссылка в библиотеках как .lib файлы вместо динамически загружая их как DLL. Вы делаете это используя флаг / MT на cl.exe командная строка (vs / MD) или выбор соответствующий вариант в вашем проекте свойства через Visual Studio. Вы может пожелать использовать эту опцию, когда тестирование ранних отладочных сборок вашего применение на тестовых машинах перед Вы начинаете работать над настройкой. [Увидеть сноска 3]

Однако я не могу придумать сценариев в котором это на самом деле право что нужно сделать при доставке вашего продукта для клиентов. В основном, что это Подход делает тянет в двоичном код, необходимый из файлов .LIB при компиляции время, делая его частью вашего .exe или .dll файлы. Это увеличивает размер ваше приложение, и нет никакого способа обновить библиотеки отдельно перекомпиляция вашего приложения с новым .LIBs и перераспределение вашего Приложение снова и снова. Что это значит, что если вы не коснетесь каждая машина, которая имеет установил ваше приложение каждый раз существует уязвимость безопасности находится в библиотеках Visual C ++ и полностью переустановите ваш обновленный двоичные файлы, вы будете оставлять свои клиенты уязвимы для атак. Если вместо этого вы используете DLL, каждый раз существует уязвимость безопасности находится в библиотеках Visual C ++, Microsoft установит обновление централизованно в папку WinSxS через Центр обновления Windows и все запросы на DLL будут перенаправлены на обновленная версия. Это удаляет все бремя обслуживания на вашей стороне, а также позволяет пользователю установить один маленький обновление, которое коснется всех их приложения вместо замены каждый установленный EXE и DLL на их система. Пожалуйста, не распространяйте приложение построено по ссылке статически против Visual C ++ библиотеки, если у вас нет системы в место для обновления каждого клиента а также машина очень хорошая причина для этого. В это время я могу не думай об обстоятельствах, при которых это было бы правильно сделать для доставки приложения.


Интересно, есть ли что-то под названием «Однопоточная отладка» и «Однопоточный», который снова вызывает то же самое.

Нет, см. Выше.


Документация говорит о «параметрах генерации кода». Какие варианты генерации кода? ЧТО они?

Щелкните правой кнопкой мыши по проекту Visual C ++ (из Visual Studio) и выберите Свойства. В свойствах конфигурации -> C / C ++ -> Генерация кода


Документация специально предупреждает нас не использовать обходной путь / NODEFAULTLIB. (пример / NODEFAULTLIB: msvcrt). Зачем? Как бы я вызвал проблемы? что именно это?

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


Пожалуйста, объясните последний пункт в документации для пользователей MFC. Потому что я собираюсь использовать MFC позже в этом проекте. Объясните, почему мы должны это делать? Какие неприятности это может вызвать, если я не буду.

Поскольку MFC динамически связан со средой выполнения C, использование библиотек, статически связанных со средой выполнения C, приведет к ошибкам компоновщика, которые вы перечислили первыми в своем посте.


Что-нибудь еще, что вы хотели бы упомянуть? Я имею в виду похожие ошибки. Я очень заинтересован в линкере и его проблемах. Итак, если есть какие-либо похожие вещи, вы можете упомянуть их или хотя бы несколько ключевых слов.

По моему опыту, всегда динамически связываться со средой выполнения C. Как правило, это избавляет вас от многих головных болей, подобных той, что вы испытываете сейчас.

...