Разница между статическими и динамическими (разделяемыми) библиотеками?
Разница между статическими и динамическими библиотеками
Я использую Eclipse и заметил, что в нем есть несколько типов проектов, включая статические библиотеки и динамические библиотеки (shared libraries). В чем заключается разница между ними? Есть ли у одного типа явные преимущества перед другим?
5 ответ(ов)
Библиотеки общего доступа представляют собой файлы с расширением .so (в Windows — .dll, в OS X — .dylib). Весь код, относящийся к библиотеке, содержится в этом файле, и программы обращаются к нему во время выполнения. Программа, использующая библиотеку общего доступа, ссылается только на тот код, который она фактически использует из этой библиотеки.
Статические библиотеки имеют расширение .a (в Windows — .lib). Вся информация, относящаяся к библиотеке, также хранится в этом файле, но она связывается непосредственно с программой на этапе компиляции. Программа, использующая статическую библиотеку, берет копии кода, который она использует, из статической библиотеки и включает его в свою собственную сборку. [В Windows также есть файлы .lib, которые используются для ссылки на .dll, но они действуют аналогично первому варианту].
Каждый из этих методов имеет свои плюсы и минусы:
Библиотеки общего доступа уменьшают количество дублированного кода в каждой программе, использующей библиотеку, что позволяет держать бинарные файлы компактными. Это также дает возможность заменять объект на другой, функционально эквивалентный, который может иметь улучшенные характеристики производительности, без необходимости перекомпиляции программы, которая его использует. Тем не менее, библиотеки общего доступа имеют небольшие дополнительные затраты на выполнение функций, а также затраты на загрузку во время выполнения, так как все символы в библиотеке необходимо связать с теми ресурсами, которыми они пользуются. Дополнительно, библиотеки общего доступа могут загружаться в приложение во время выполнения, что является общим механизмом для реализации систем бинарных плагинов.
Статические библиотеки увеличивают общий размер бинарного файла, однако это означает, что вам не нужно носить с собой копию используемой библиотеки. Поскольку код связывается на этапе компиляции, дополнительных затрат на загрузку во время выполнения нет. Код просто присутствует в программе.
Лично я предпочитаю библиотеки общего доступа, но использую статические библиотеки, когда требуется гарантировать, что бинарный файл не будет содержать множество внешних зависимостей, с которыми может возникнуть трудность, например, конкретные версии стандартной библиотеки C++ или конкретные версии библиотеки Boost C++.
Статическая библиотека похожа на книжный магазин, а общая библиотека — на обычную библиотеку. В случае со статической библиотекой вы получаете свою собственную копию книги/функции, которую можете взять с собой; в случае с общей библиотекой вы и другие пользователи приходите в библиотеку, чтобы использовать одну и ту же книгу/функцию. Поэтому любой, кто хочет воспользоваться (общей) библиотекой, должен знать, где она находится, поскольку вам нужно «сходить» за книгой/функцией. Со статической библиотекой книга/функция принадлежит вам, вы храните её в своём доме/программе, и как только вы её получили, вам уже не важно, откуда и когда вы её взяли.
В статической компоновке (static linking) создается один большой исполняемый файл, который содержит все необходимые библиотеки внутри него. Это означает, что все зависимости уже включены в итоговый файл, и для его работы не нужны дополнительные библиотеки.
В динамической компоновке (dynamic linking) создается небольшой исполняемый файл, который ссылается на одну или несколько библиотек, находящихся отдельно от него. На Windows это .dll файлы, на Linux – .so файлы, а на macOS – .dylib файлы. Это позволяет уменьшить размер исполняемого файла, но требуется наличие библиотек на целевой системе для его запуска.
Для статической библиотеки код извлекается из библиотеки компоновщиком (linker) и используется для сборки конечного исполняемого файла в момент компиляции вашего приложения. Конечный исполняемый файл не имеет зависимостей от библиотеки во время выполнения.
Для динамической (разделяемой) библиотеки компилятор/компоновщик проверяет наличие имен, с которыми вы связываетесь, в библиотеке на этапе сборки приложения, но не переносит их код в само приложение. Во время выполнения разделяемая библиотека должна быть доступна.
Сам язык C не имеет концепции статических или динамических библиотек - это полностью особенность реализации.
Лично я предпочитаю использовать статические библиотеки, так как это упрощает распределение программного обеспечения. Однако это мнение, по которому в прошлом было "пролито много (фигуральной) крови".
Статические библиотеки компилируются как часть приложения, тогда как разделяемые библиотеки (shared libraries) таковыми не являются. Когда вы распространяете приложение, которое зависит от разделяемых библиотек, такие как .dll на MS Windows, эти библиотеки должны быть установлены.
Преимущество статических библиотек в том, что пользователю, запускающему приложение, не нужны дополнительные зависимости - например, не нужно обновлять свою DLL. Недостаток заключается в том, что ваше приложение занимает больше места, так как вы поставляете его вместе со всеми необходимыми библиотеками.
Разделяемые библиотеки позволяют создать более компактные приложения и дают пользователям возможность использовать свои версии библиотек, возможно, более качественные, вместо того чтобы полагаться на те, что включены в приложение.
Как изменить цвет вывода echo в Linux
Разница между const int*, const int * const и int * const?
Почему переменные нельзя объявлять в операторе switch?
Что такое ошибка сегментации?
Самый быстрый способ проверить существование файла с использованием стандартного C++/C++11, C++14, C++17/C?