Разница между статическими и общими библиотеками?

561

В чем разница между статическими и общими библиотеками?

Я использую Eclipse, и есть несколько типов проектов, включая статические библиотеки и общие библиотеки? У одного есть преимущество перед другим?

Мохит Дешпанде
источник
4
В Википедии есть хорошее описание различия между статическими, динамическими и общими библиотеками.
Адам Холмберг

Ответы:

746

Общие библиотеки - это файлы .so (или в Windows .dll, или в OS X .dylib). Весь код, относящийся к библиотеке, находится в этом файле, и на него ссылаются программы, использующие его во время выполнения. Программа, использующая общую библиотеку, ссылается только на код, который она использует в общей библиотеке.

Статические библиотеки - это файлы .a (или в Windows .lib). Весь код, относящийся к библиотеке, находится в этом файле, и он напрямую связан с программой во время компиляции. Программа, использующая статическую библиотеку, берет копии кода, который она использует, из статической библиотеки и делает ее частью программы. [В Windows также есть файлы .lib, которые используются для ссылки на файлы .dll, но они действуют так же, как и первый].

У каждого метода есть свои преимущества и недостатки:

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

  • Статические библиотеки увеличивают общий размер двоичного файла, но это означает, что вам не нужно иметь при себе копию используемой библиотеки. Поскольку код подключен во время компиляции, никаких дополнительных затрат на загрузку во время выполнения не возникает. Код просто там.

Лично я предпочитаю разделяемые библиотеки, но использую статические библиотеки, когда необходимо убедиться, что двоичный файл не имеет много внешних зависимостей, которые могут быть трудно встретить, таких как конкретные версии стандартной библиотеки C ++ или конкретные версии библиотеки Boost C ++.

Petesh
источник
2
«заменить совместно используемый объект ... функционально эквивалентным, но может [улучшить] производительность»: в частности, эквивалентными функциональными возможностями, обращенными к вызывающей стороне, в семантическом использовании API (интерфейс прикладного программирования: сигнатуры функций и переменные, включая типы), но на стороне реализации функциональность может отличаться не только от перф .: например, функция всегда записывает в файл -> также регистрируется на TCP-сервере: ожидается порт в $ MY_APP_LOG_SERVER.
Тони Делрой
1
«[.SOS несут] небольшую дополнительную плату за выполнение функций» - это возможно (если группы функций / порядок были оптимизированы для размещения кэша в статической ссылке или из-за странностей в ОС / загрузчике / компиляторе / архитектуре, таких как cross -segment / Large-указатель перф. штрафов), но во многих архитектурах / настройках компилятора динамический компоновщик исправляет вызов, чтобы создать точно такие же коды операций вызывающей машины.
Тони Делрой
2
«Поскольку код подключен во время компиляции, никаких дополнительных затрат на загрузку во время выполнения не возникает. Код просто есть». - да и нет ... это все в исполняемом образе, готовом для вставки, если требуется выполнение, но - начиная с ситуации, когда ваша программа запускалась недостаточно недавно, чтобы находиться в кеше - с общими библиотеками это возможно (иногда вероятно или уверен), что ОС, драйвер или другая работающая программа уже загрузили ту же общую библиотеку, которую хочет использовать ваше приложение, и в этом случае она может находиться в кеше, и ваша программа запускается и работает быстрее.
Тони Делрой
15
Некоторые люди не смогли упомянуть, что со статическими библиотеками компилятор знает, какие функции нужны вашему приложению, и затем может оптимизировать его, включив только эти функции. Это может существенно сократить размер библиотеки, особенно если вы используете только очень маленькое подмножество действительно большой библиотеки!
jduncanator
1
Этот ответ может быть лучше организован. Было бы полезно составить списки для плюсов / минусов или таблицу, чтобы показать различия в каждом измерении, где есть различия.
ElefEnt
377

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

Пол Рихтер
источник
70

Упрощенная:

  • Статическое связывание: один большой исполняемый файл
  • Динамическое связывание: небольшой исполняемый файл плюс один или несколько библиотечных файлов (файлы .dll в Windows, .so в Linux или .dylib в macOS)
StackedCrooked
источник
1
Этот ответ является лучшим для меня, потому что это практично. Это имеет гораздо больше смысла, чем метафора, которая не говорит о том, что на самом деле происходит в компьютере. Зная, что это то, что происходит, я просто интуитивно знаю все другие последствия.
off99555
36

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

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

Сам язык программирования C не имеет понятия ни о статических, ни о разделяемых библиотеках - они полностью реализованы.

Лично я предпочитаю использовать статические библиотеки, поскольку это упрощает распространение программного обеспечения. Тем не менее, это мнение, по которому много (фигуративной) крови пролилось в прошлом.


источник
5
+1 за «Сам язык программирования C не имеет понятия ни о статических, ни о разделяемых библиотеках - они полностью реализованы».
Тигр
1
Привет anon / @Tiger, почему вы заявили: «Сам язык программирования C не имеет понятия ни о статических, ни о разделяемых библиотеках - они полностью являются функцией реализации».? Можете ли вы объяснить немного подробнее или указать мне соответствующую ссылку?
Сунил Шаху
@SunilShahu Способ компиляции и компоновки программы зависит от используемого компилятора и компоновщика, то есть от конкретной реализации языка. Спецификации языка обычно не описывают, как языки должны быть реализованы или построены, только функциональность, синтаксис, грамматика и т. Д.
JC Rocamonde
@SunilShahu более очевидными примерами может быть, например, JavaScript, где спецификация (EcmaScript) описывает особенности языка, но это разные поставщики, которые поставляют интерпретаторы JS (например, движки браузера или Node.js). С другой стороны, язык программирования Python имеет несколько реализаций. Официальный - CPython, но есть и другие, написанные на других языках.
JC Rocamonde
31

Статические библиотеки компилируются как часть приложения, тогда как разделяемые библиотеки - нет. Когда вы распространяете приложение, которое зависит от общих библиотек, библиотек, например. DLL на MS Windows должны быть установлены.

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

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

Тарский
источник
3
DLL ад, как это было известно
гуси
1
«Статические библиотеки скомпилированы как часть приложения» ... статические библиотеки скомпилированы как статические библиотеки и связаны как часть приложения
idclev 463035818
19

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

OTOH, преимущество статических библиотек состоит в том, что все включено в ваше приложение. Поэтому вам не нужно беспокоиться о том, что у клиента будет правильная библиотека (и версия), доступная в его системе.

Jasmeet
источник
1
Исполняемый образ больше на диске, а также в памяти, при использовании статических библиотек.
JustJeff
Это правильно, это то, на что я ссылался, когда говорил, что все включено в ваше приложение.
Жасмит
Кроме того, .soфайлы в системах * nix являются своего рода общей (динамической) библиотекой.
ОСШ
6

Вдобавок ко всем остальным ответам, еще не упомянуто одно:

Позвольте мне рассказать о реальном производственном коде, с которым я имел дело:

Очень большое программное обеспечение, состоящее из> 300 проектов (с Visual Studio), в основном построенное как статическая библиотека и, наконец, все объединенное в один огромный исполняемый файл, вы сталкиваетесь со следующими проблемами:

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

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

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

sandwood
источник
2
-------------------------------------------------------------------------
|  +-  |    Shared(dynamic)       |   Static Library (Linkages)         |
-------------------------------------------------------------------------
|Pros: | less memory use          |   an executable, using own libraries|
|      |                          |     ,coming with the program,       |
|      |                          |   doesn't need to worry about its   |
|      |                          |   compilebility subject to libraries|
-------------------------------------------------------------------------
|Cons: | implementations of       |   bigger memory uses                |
|      | libraries may be altered |                                     |
|      | subject to OS  and its   |                                     |
|      | version, which may affect|                                     |
|      | the compilebility and    |                                     |
|      | runnability of the code  |                                     |
-------------------------------------------------------------------------
ОСШ
источник