Ошибка ссылки: xxx уже определяется в *****.LIB:: Что точно является неправильным?

Проблема:

Я пытаюсь пользоваться библиотекой под названием 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 

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

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

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

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

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

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

Огромная Сумма Проблем Компоновщика со Сборкой конечных версий Только говорит:

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

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

Вопросы:

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

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

  2. Интересно, существует ли что-то позвонившее "Однопоточная Отладка" и "Однопоточный", который снова вызывает то же самое.

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

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

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

5
задан Community 23 May 2017 в 12:13
поделиться

3 ответа

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

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

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

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

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

В документации что-то говорится о «Параметры генерации кода». Какие варианты создания кода ? Зачем они?

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

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

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

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

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

8
ответ дан 14 December 2019 в 04:33
поделиться

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

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

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

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

0
ответ дан 14 December 2019 в 04:33
поделиться

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

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

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

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

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


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

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


В документации что-то говорится о «Опциях генерации кода». Какие варианты генерации кода? Зачем они?

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


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

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


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

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


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

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

0
ответ дан 14 December 2019 в 04:33
поделиться