Что такое библиотеки в программировании на C?

В общем смысле библиотеки — это наборы предварительно скомпилированных функций, написанных для повторного использования другими программистами. Библиотеки состоят из набора связанных функций для выполнения общей задачи; например, стандартная библиотека C, libc.a, автоматически подключается к вашим программам компилятором gcc, и ее можно найти в /usr/lib/libc.a. Стандартные системные библиотеки обычно находятся в каталогах /lib и /usr/lib/. Проверьте эти каталоги. По умолчанию компилятор gcc или, точнее, его компоновщик должны быть направлены на библиотеки для поиска, кроме стандартной библиотеки C, которая включена по умолчанию.

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

.a: статические, традиционные библиотеки. Приложения ссылаются на эти библиотеки объектного кода.

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

Подробнее о статических библиотеках можно прочитать здесь.

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

Динамические библиотеки ведут себя немного иначе. Они считаются более гибкими в отношении внесения изменений и обмена ими, поскольку они загружаются в программу во время выполнения, а не превращаются в фактический исполняемый файл. Вы можете определить динамическую библиотеку на компьютере с Linux по ее расширению «.so», которое указывает, что это общийобъект. В процессе компиляции:

  1. Препроцессор — строки, начинающиеся с «#», интерпретируются в этом процессе и передаются как простые макросы. Также и любые комментарии, предназначенные только для человеческого глаза, удаляются.
  2. Компиляция. На этом этапе код готов к преобразованию в язык ассемблера, который по своей форме все еще в некоторой степени читабелен.
  3. Assembly — код сборки затем превращается в объектный код (также известный как машинный код).
  4. Связывание — на этом заключительном этапе отсутствующие фрагменты кода (такие элементы, как заголовочные файлы или библиотеки, необходимые для завершения кода) окончательно связываются с объектом, прежде чем превратить его в исполняемый файл.

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

gcc -Wall -pedantic -Werror -Wextra -c -fPIC *.c

  • преобразует исходный код (файлы .c) в объектный код (файлы .o) с использованием флага -c.
  • Флаг -fPIC: означает позиционно-независимый код. Необходимо, чтобы системы и процессоры создавали библиотеки, чтобы они могли решить, куда они хотят загрузить их в память.

gcc -shared *.o -o libname.so

  • Флаг -shared сообщает gcc, что вы хотите преобразовать объект .code (файлы .o) в общие объектные файлы (.so), также известные как динамические библиотеки на компьютерах Linux и Unix.

Если вы хотите заглянуть в свой общий объектный файл, чтобы увидеть, из чего состоят функции, используйте:

nm -D libname.so

  • nm символы списка команд из объектных файлов
  • Флаг -D относится к символам в разделе инициализированных данных.

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

На компьютерах Unix и Linux должна быть установлена ​​переменная пути к библиотеке, чтобы ваша программа знала, где найти библиотеку. Если библиотека не находится в папке /usr/lib .

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

  • Вы устанавливаете LD_LIBRARY_PATH, которая является глобальной переменной, для вашего текущего каталога (.)
gcc -Wall -pedantic -Werror -Wextra -L. main.c -llibname
  • Флаг -L указывает флагу искать в указанном каталоге, в нашем случае это текущий каталог (.)
  • -l с soname, которое представляет собой имя библиотеки без префикса lib и суффикса .so.

Преимущества использования динамических библиотек

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

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