Примечание: следующий ответ не не зависит от платформы, но специфичен для систем на базе ELF и некоторых других подобных. Кто-то другой может заполнить данные для других систем.
Что такое статическая библиотека?
Статическая библиотека - это коллекция *.o
файлов в архиве. Каждый файл может содержать ссылки на неопределенные символы, которые должны быть разрешены компоновщиком, например, ваша библиотека может иметь ссылку на printf
. Библиотека не предоставляет никаких указаний о том, где будет найден printf
, ожидается, что компоновщик найдет его в одной из других библиотек, в которых его просят связать.
Предположим, ваша библиотека содержит следующий код:
read_png.o
write_png.o
read_jpg.o
write_jpg.o
resize_image.o
handle_error.o
Если приложение использует только read_png
и write_png
, то другие части кода не будут загружены в исполняемый файл (кроме handle_error
, который вызывается из read_png
и write_png
).
Мы не можем загрузить статическую библиотеку во время выполнения, потому что:
Компоновщик не знает, где найти внешние объекты, например, printf
.
Это будет медленно. Динамические библиотеки оптимизированы для быстрой загрузки.
Статические библиотеки не имеют понятия пространств имен. Я не могу определить свой собственный handle_error
, потому что это будет противоречить определению библиотеки.
Что такое динамическая библиотека?
Динамическая библиотека в системах ELF - это объект того же типа, что и исполняемый файл. Он также экспортирует больше символов, исполняемый файл требуется только для экспорта _start
. Динамические библиотеки оптимизированы, поэтому все это может быть отображено непосредственно в память.
Если у вас есть вызов printf
в вашей динамической библиотеке, существуют некоторые дополнительные требования, помимо требований для статических библиотек:
Вы должны указать, какая библиотека имеет printf
.
Вы должны вызывать функцию особым образом, чтобы компоновщик мог вставить адрес для printf
. В статической библиотеке компоновщик может просто изменить ваш код и вставить адрес напрямую, но это невозможно с общими библиотеками.
Мы не хотим использовать динамические библиотеки для статического связывания, потому что:
Мы не можем связать только часть динамической библиотеки. Даже если наш исполняемый файл никогда не вызывает read_jpg
, он включается, потому что динамические библиотеки все или ничего.
Дополнительные затраты на вызовы функций расточительны, даже если они небольшие.
Резюме
Компиляция выглядит примерно так:
Source ==compile==> Object ==link==> Executable / Shared Library
Статическая библиотека - это архив, полный объектов, которые еще не были связаны. Осталось проделать большую работу.
Общая библиотека - это связанный конечный продукт, готовый для загрузки в память.
Статические библиотеки были изобретены первыми. Если бы оба были изобретены одновременно, возможно, они были бы намного более похожими.