Несоответствие библиотеки времени выполнения и VC ++ - Ах, какое несчастье!

Похоже, что всю свою сознательную жизнь меня мучили жалобы или возражения компоновщика VC ++ из-за того, что различные библиотеки не договариваются о том, какую версию библиотеки времени выполнения использовать. Я никогда не в настроении осваивать этот мрачный предмет. Так что я просто пытаюсь возиться с этим, пока он не сработает. Сообщения об ошибках бесполезны. В документации Microsoft по этому поводу тоже нет - по крайней мере, для меня.

Иногда он не находит функции - потому что изменение имени не то, что ожидалось? Иногда он отказывается смешивать и сочетать. В других случаях он просто говорит: «ССЫЛКА: предупреждение LNK4098: defaultlib 'LIBCMTD' конфликтует с использованием других библиотек; использование / NODEFAULTLIB: библиотека» Использование / NODEFAULTLIB не работает, но предупреждение кажется безобидным . Что, черт возьми, такое "DEFAULTLIB"? Как решает компоновщик? Я никогда не видел способа указать компоновщику, какую библиотеку времени выполнения использовать, только как сообщить компилятору, для какой библиотеки создавать вызовы функций.

Существуют программы «обходчика зависимостей», которые могут проверять объектные файлы, чтобы увидеть, от каких DLL они зависят. Я только что запустил один в проекте, который пытаюсь создать, и это настоящий беспорядок. Существуют системные библиотеки .lib и .dll, которым требуются конфликтующие версии среды выполнения. Например, COMCTL32.DLL требуется MSVCRT.DLL, но я связываюсь с MSVCRTD.DLL. Я ищу, есть ли COMCTL32D.DLL, даже когда я печатаю.

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

Вот что я знаю. Пожалуйста, поправьте меня, если что-то не так.

  1. Параметры: Debug / Release, Multi-thread / Single-thread и static / DLL. Охватываются только шесть из восьми возможных комбинаций. Нет однопоточной DLL, ни отладки, ни выпуска.

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

Бонусный вопрос: как кто-то или любая компания может создать такой беспорядок?


person Jive Dadson    schedule 02.03.2010    source источник


Ответы (1)


Ваши пункты (1) и (2) мне кажутся правильными. Еще одна вещь, которую следует отметить в отношении (2), заключается в том, что связывание в CRT отладки также дает вам доступ к таким вещам, как расширенная проверка кучи, проверенные итераторы и другие различные проверки работоспособности. Однако вы не можете распространять отладочную CRT вместе с вашим приложением - вы должны поставлять только с использованием сборки выпуска. Это не только требуется по лицензии VC, но вы, вероятно, в любом случае не захотите отправлять двоичные файлы отладки.

Не существует такой вещи, как COMCTL32D.DLL. DLL, которые являются частью Windows, должны загружать CRT, с которым они были связаны при сборке Windows - это включено в ОС как MSVCRT.DLL. Этот Windows CRT полностью независим от Visual C ++ CRT, который загружается модулями, составляющими вашу программу (MSVCRT.DLL - это тот, который поставляется с Windows. CRT VC будет включать номер версии, например MSVCRT80.DLL). Только файлы EXE и DLL, составляющие вашу программу, подвержены влиянию многопоточных / однопоточных параметров отладки / выпуска.

Лучшая практика здесь, IMO, - выбрать настройку для вашего CRT и стандартизировать ее для каждого отправляемого вами двоичного файла. Я лично использую многопоточную среду выполнения DLL. Это связано с тем, что Microsoft может (и выпускает) обновления безопасности и исправления ошибок для CRT, которые можно отправить через Центр обновления Windows.

person Aaron Klotz    schedule 02.03.2010
comment
Превосходно! Я думаю, что понимаю, но оставляю за собой право задавать вопросы, когда неизбежно обнаруживаю, что не понимаю. Кстати, в проекте, над которым я сейчас работаю, я получаю как Release, так и Debug для связывания и запуска, но версия Release сообщает мне: LINK: warning LNK4098: defaultlib 'LIBCMT' конфликтует с использованием других библиотек; используйте / NODEFAULTLIB: библиотека. Меня это сбивает с толку, потому что я выбрал многопоточную DLL для генерации кода (/ MD). Ссылки на отладочную версию чистые. Я связываюсь с wxWidgets, lcms, opencv и всем остальным, что они тянут. Вперед, сквозь туман! - person Jive Dadson; 02.03.2010
comment
Я обнаружил, как использовать / NODEFAULTLIB: libray в среде VC ++ IDE. Откройте Properties, а затем страницу Linker / Input. Введите имя вызывающей ошибку DEFAULTLIB в текстовое поле Игнорировать конкретную библиотеку. - person Jive Dadson; 02.03.2010