Статические и динамические библиотеки

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

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

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

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

Здесь мы обсудим два разных типа библиотек - статические и динамические.

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

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

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

Как создать статическую библиотеку?

Давайте создадим статическую библиотеку, используя все файлы * .c в нашем текущем каталоге. Сначала нам нужно скомпилировать наши файлы C в объектный код. Мы можем сделать это, используя:

Далее нам нужно создать нашу статическую библиотеку и добавить в нее файлы. Сделать это можно с помощью команды:

После того, как мы добавили все в нашу стандартную библиотеку, необходимо проиндексировать библиотеку. Индексировать библиотеку можно, выполнив команду ranlib libexample.a. Индексирование библиотеки важно, поскольку оно ускоряет процесс связывания при вызове библиотеки.

Мы можем просмотреть наш недавно созданный индекс, выполнив команду nm libstatic.a. Команда Nm предоставляет дополнительную информацию о символах в нашей статической библиотеке. В частности, по умолчанию команда nm покажет нам виртуальный адрес символа, имя символа и информацию о типе символов. Если символ в нижнем регистре, он локальный, если он написан в верхнем регистре, он внешний.

Чтобы использовать эту статическую библиотеку, мы должны создать программу - назовем ее my_program.c, которая использует функции из только что созданной библиотеки. Чтобы использовать библиотечные функции, нам нужно указать компилятору, где искать. Мы могли запустить команду:

Теперь давайте посмотрим на динамические библиотеки. Давайте представим знакомый сценарий, у нас есть файл исходного кода, который вызывает функцию из библиотеки mylib.so (обратите внимание на разницу в расширениях файлов. В Linux статические библиотеки должны оканчиваться на «.a», а динамические библиотеки должны заканчиваться на «. так"). Вместо того, чтобы фактически компилировать реализацию функции в объектный код и включать ее в исполняемый файл в динамическую библиотеку, компоновщик просто включит адрес начала функции, которую мы пытаемся использовать в исполняемом файле. Это устраняет проблему размера, вызванную статическими библиотеками, поскольку окончательный исполняемый файл будет включать только адреса, а не целые реализации функций.

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

Как создать динамическую библиотеку?

Давайте создадим динамическую библиотеку, используя все файлы * .c в нашем текущем каталоге. Сначала нам нужно скомпилировать наши файлы C в объектный код и сделать их независимыми от позиции. Мы можем сделать это, используя:

Далее нам нужно создать нашу динамическую библиотеку и добавить в нее файлы. Сделать это можно с помощью команды:

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

Программа должна знать, где искать файлы библиотеки. Следовательно, мы должны добавить расположение динамической библиотеки в окружение LD_LIBRARY_PATH. Мы могли бы сделать это с помощью следующей команды:

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

Чтобы использовать эту динамическую библиотеку (liball.so), мы должны создать программу - назовем ее my_program.c. Допустим, эта программа использует функции из нашей динамической библиотеки. Затем нам нужно скомпилировать программу так же, как мы делали статическую библиотеку:

gcc -lliball -L. my_program.c -o программа.

После создания этой новой разделяемой библиотеки мы можем использовать команду ldconfig для создания необходимых ссылок и кеширования (для использования компоновщиком времени выполнения, ld.so) с /etc/ld.so Каталог .conf.

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