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

Зачем вообще использовать библиотеки

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

Как они работают

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

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

Как их создать (только для Linux)

давайте возьмем пример, сначала нам нужно создать заголовочный файл

пример.h

#ifndef HEADER
#define HEADER
#include <stdio.h>
int add(int a, int b); // adds two integers
#endif

далее создадим файл add.c

доп.с

#include "example.h"
int add(int a, int b)
{
  return (a + b);
}

Теперь скомпилируйте add.c, чтобы получить двоичный объектный файл.

Статический:

vagrant@vagrant-ubuntu-trusty-64:~$ gcc -c add.c

Динамический:

vagrant@vagrant-ubuntu-trusty-64:~$ gcc -c -fPIC add.c

Параметр «-c» гарантирует, что процесс компиляции остановится до компоновщика и создаст файл «add.o».

Теперь у нас есть двоичный объектный файл add.o, и теперь мы можем создать статическую и динамическую библиотеку libtest, выполнив следующую команду:

Статический:

vagrant@vagrant-ubuntu-trusty-64:~$ ar rc libtest.a add.o

в приведенной выше команде мы используем команду ar для создания файла ‘.a’.

Динамический:

vagrant@vagrant-ubuntu-trusty-64:~$ gcc -shared -o libtest.so add.o

в приведенной выше команде мы используем команду gcc с флагами '-shared' и '-o'optionпотому что мы компилируем из объектного файла, чтобы создать файл '.so'.

Как их использовать (только для Linux)

Теперь, когда у нас есть библиотека, мы должны использовать ее для компиляции и создания нашей программы. Допустим, наша точка входа находится в файле «main.c», и мы хотим назвать нашу программу «добавить». Вот команда для компиляции программы с нашей библиотекой в ​​обоих случаях:

vagrant@vagrant-ubuntu-trusty-64:~$ gcc -L. main.c -ltest -o add

Флаг '-L' сообщает компилятору, где ему нужно искать библиотеку, поэтому в этом случае, когда библиотека находится в текущем рабочем каталоге, мы просто используем точку. '-ltest' указывает компилятору связать код в main.c с кодом в библиотеке my_lib. Наконец, флаг '-o' позволяет нам дать имя исполняемому файлу, в данном случае это будет «добавить».

Вот чем динамические библиотеки отличаются от статических. Со статической библиотекой мы можем просто запустить код прямо сейчас. Но с динамической библиотекой это не сработает. Полезным инструментом для демонстрации этого является ldd, команда, которая печатает зависимости общих библиотек. В нашем случае вывод «ldd add» будет содержать строку, в которой говорится:

libtest.so => not found

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

vagrant@vagrant-ubuntu-trusty-64:~$ export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

Давайте еще раз попробуем «ldd add», и результат будет таким:

libtest.so => ./libtest.so (0x00007fd4bf2d9000)

Помимо ldd для зависимостей, мы можем использовать команду 'nm' для проверкисимволов динамической библиотеки. Эти символы включают функции, определенные в библиотеке. Для динамических библиотек мы используем флаг -D, например:

vagrant@vagrant-ubuntu-trusty-64:~$ nm -D libtest.so

Теперь, когда мы уверены, что динамическая библиотека создана и ее можно использовать, мы можем запустить нашу программу, набрав

vagrant@vagrant-ubuntu-trusty-64:~$ ./add

Каковы преимущества и недостатки каждого из них

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

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

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

Последнее слово

В этом руководстве мы обсудили, как статическая и динамическая компоновка в C выполняется для статических и разделяемых библиотек (библиотек динамической компоновки — DLL). Надеюсь, вам понравилось читать этот урок. Пожалуйста, напишите нам, если у вас есть какие-либо предложения/комментарии или вы столкнетесь с какой-либо ошибкой на этой странице. Спасибо за чтение!

Источники