С++: разница между библиотекой ссылок и добавлением включают каталоги

Довольно много заголовков подводит итог.

Я не уверен, что разница между этими двумя, если я хочу использовать библиотеку.

Благодарю!

Ответ 1

В общем, вам нужны оба.

Включить файлы содержат декларации типов, прототипов функций, inline функций, #define s,..., в общем, вся информация о библиотеке, о компилере которой необходимо знать при компиляции ваших файлов.

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

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

Эта концепция очень похожа на то, когда вы компилируете многофайловый проект: для доступа к определениям, написанным в другом .cpp вам нужно включить только заголовок с их объявлениями, а компоновщик в конце связывает вместе различные объектные модули.

Что касается DLL, то обычно предоставляется библиотека импорта; библиотеки импорта похожи на статические библиотеки, но вместо того, чтобы содержать весь код библиотеки, они содержат небольшие заглушки, которые вызывают функции в dll. Каждый раз, когда вызов функции библиотеки встречается в одном из ваших объектных модулей, компоновщик направляет его на заглушку, которая, в свою очередь, перенаправляет ее в код в dll 1. В общем, при работе с dll на Windows у вас обычно есть .h (prototypes/...), .lib (импортирующая библиотека, на которую вы ссылаетесь, содержит заглушки) и .dll (библиотека динамической компоновки, содержащая фактические код библиотеки).

Кстати, некоторые библиотеки "только для заголовков" (вы можете найти много в boost), а это значит, что весь их код помещается в заголовок, поэтому не требуется статическая библиотека. Такие библиотеки часто просто состоят из встроенного кода (функции/классы/...) и шаблонов, для которых не требуется отдельного определения.

Часто это делается потому, что статические библиотеки - уродливые звери по нескольким причинам:

  • вы должны явно ссылаться на них;
  • поскольку они связаны непосредственно с вашим кодом, они должны использовать точно такую же библиотеку времени выполнения C/C++, что означает, что, по крайней мере, в Windows, нецелесообразно распространять статические библиотеки (разные компиляторы, разные версии компилятора, различные конфигурации один и тот же компилятор использует разные стандартные библиотеки, распределяя статическую библиотеку для каждой комбинации этих аспектов, по крайней мере, нецелесообразно);
  • из-за этого, в общем, вы должны сначала скомпилировать свою собственную версию статической библиотеки, а затем связать ее.

Сравните все это, просто включив заголовочный файл... :)


  1. Фактически, современные инструментальные цепочки могут распознавать эти заглушки и избегать дополнительного направления косвенности. Смотрите эту серию Раймондом Ченом для подробностей.

Ответ 2

Компилятор должен знать каталоги include, так как он должен включать файлы заголовков (интерфейса) библиотек, которые вы хотите использовать.

Компилятор должен знать каталоги библиотек, так как он должен связать ваш исполняемый файл с (предварительно скомпилированной) реализацией библиотеки.

См. Также Каковы различия между компилятором и компоновщиком?

Ответ 3

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

См. Этот вопрос.