Что такое библиотеки в C

Что такое библиотеки в C? В C библиотеки — это файлы, содержащие набор функций, которые обычно используются в любой из ваших программ, например функция printf. Существует два типа библиотек: статические и динамические; они связаны с вашими программами в процессе компиляции, когда вы GCC получаете файл, содержащий ваши программы. Когда библиотеки связаны с вашей программой, программа теперь может получить доступ к функциям, которые были определены в библиотеке.

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

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

Статические библиотеки

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

Давайте рассмотрим краткий обзор того, как создать статическую библиотеку:

#To create a static library:
#First, compile all your .c files 
$ gcc -c *.c
#Each .c file now has a .o file associated - it's object file
$ ls
total 10
-rw-rw-r-- 1 ubuntu ubuntu 89 Mar 25 02:44 abs.c
-rw-rw-r-- 1 ubuntu ubuntu 1400 Mar 25 02:47 abs.o
-rw-rw-r-- 1 ubuntu ubuntu 132 Mar 25 02:44 isupper.c
-rw-rw-r-- 1 ubuntu ubuntu 1408 Mar 25 02:47 isupper.o
-rw-rw-r-- 1 ubuntu ubuntu 132 Mar 25 02:44 _putchar.c
-rw-rw-r-- 1 ubuntu ubuntu 1408 Mar 25 02:47 _putchar.o
-rw-rw-r-- 1 ubuntu ubuntu 166 Mar 25 02:44 strlen.c
-rw-rw-r-- 1 ubuntu ubuntu 1464 Mar 25 02:47 strlen.o
-rw-rw-r-- 1 ubuntu ubuntu 162 Mar 25 02:44 holberton.h
#Using the ar command to create your static library called libholberton.a
$ ar -rc libholberton.a *.o
#Now we index the library as it allows the compiler to speed up the process of searching inside the library as each object file now has a symbol associated with it. 
#To create the index, we will use the ranlib command
$ ranlib libholberton.a
#You are now free to use your static library
EXAMPLE:
$ main.c

int main(void)
{
    char c;

    c = 'A';
    printf("%c: %d\n", c, _isupper(c));
    c = 'a';
    printf("%c: %d\n", c, _isupper(c));
    return (0);
}
#gcc command on main.c
$ gcc main.c -L. -lholberton -o isupper
#Compiling the main.c file with the static library holberton and outputting it into the executable isupper.
1. -L --> option to tell gcc to search for a library in the specified directory
2. -l --> option to tell gcc to search in a specific library. In this case, holberton. We don't need to add "lib" or ".a" since the -l option shortens the name and automatically prefixes "lib" and ".a". l for lib and holberton for the library's name
3. -o --> output the executable to a specific name, isupper
--------------------------------------------------------------------
#Running the isupper program
$./isupper
A: 1
a: 0
#We've successfully ran the isupper program in our main.c file.

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

Что такое динамические библиотеки? Динамические библиотеки также создаются из всех объектных файлов, содержащих ваши функции, но их отличие заключается в том, как библиотека связана. В отличие от статических библиотек, динамические библиотеки являются общими; например, вам не нужно прикреплять файл статической библиотеки к каждой программе, поскольку динамическая библиотека загружается либо (1) во время выполнения вашей программы, либо (2) связывается во время выполнения, в то же время сохраняя статическую осведомленность .

Статические библиотеки создаются как архив или .a, а динамические библиотеки создаются как общий объектный файл или .so.

Давайте рассмотрим пример:

#To create a dynamic library:
#First, compile all your .c files
$ gcc -Wall -Werror -c -fPIC *.c
#Each .c file now has a .o file associated - it's object file
$ ls
total 10
-rw-rw-r-- 1 ubuntu ubuntu 89 Mar 25 02:44 abs.c
-rw-rw-r-- 1 ubuntu ubuntu 1400 Mar 25 02:47 abs.o
-rw-rw-r-- 1 ubuntu ubuntu 132 Mar 25 02:44 isupper.c
-rw-rw-r-- 1 ubuntu ubuntu 1408 Mar 25 02:47 isupper.o
-rw-rw-r-- 1 ubuntu ubuntu 132 Mar 25 02:44 _putchar.c
-rw-rw-r-- 1 ubuntu ubuntu 1408 Mar 25 02:47 _putchar.o
-rw-rw-r-- 1 ubuntu ubuntu 166 Mar 25 02:44 strlen.c
-rw-rw-r-- 1 ubuntu ubuntu 1464 Mar 25 02:47 strlen.o
-rw-rw-r-- 1 ubuntu ubuntu 162 Mar 25 02:44 holberton.h

Давайте ненадолго остановимся, чтобы пройтись по процессу компиляции; вы могли заметить дополнительную опцию fPIC в $ gcc -Wall -Werror -c -fPIC *.c.

Что такое fPIC? Опция fPIC или fpic «включить генерацию кода, независимую от позиции» — это требование для разделяемых библиотек. По сути, для генерации кода мы используем опцию fPIC или fpic. Я рекомендую использовать fPIC вместо fpic, поскольку fPIC не имеет ограничений из-за своего размера, поскольку fpic имеет ограничения, зависящие от платформы, для создания меньшего кода.

Создадим библиотеку:

#Using the shared option in gcc, we now create the dynamic library
$ gcc -shared -o libholberton.so *.o

Использовать динамическую библиотеку не так просто, как статическую библиотеку, поскольку вам нужно будет установить ее, чтобы иметь возможность использовать ее в нескольких программах. Во-первых, нам нужно понять ldconfig и LD_LIBRARY_PATH.

Что происходит с вашей попыткой gcc -Wall -Werror main.c -o testlibrary -ltestlibrary ? Вы можете получить сообщение об ошибке, говорящее о том, что компоновщик не может найти файл testlibrary. Существуют места по умолчанию, которые компилятор gcc будет искать, и вашего каталога может не быть в списке; для этого мы добавляем опцию -L: gcc -L -Wall -Werror main.c -o testlibrary -ltestlibrary

./testlibrary
./testlibrary: error while loading shared libraries: testlibrary.so: cannot open shared object file: No such file or directory

Теперь загрузчик не может найти разделяемую библиотеку, так как она находится не в стандартном месте; именно здесь появляется переменная окружения LD_LIBRARY_PATH, так как нам нужно сообщить загрузчику, где найти библиотеку.

export LD_LIBRARY_PATH=/home/user/Project_Ramen:$LD_LIBRARY_PATH

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

Разница

Основное различие между статической и динамической библиотекой заключается в том, как они связаны. Преимущество по сравнению со статической библиотекой заключается в том, что динамическую библиотеку можно использовать совместно, что означает, что мы можем просто ссылаться на одну библиотеку для нескольких программ, не имея при себе файла. Заголовок <stdio.h> содержит динамическую библиотеку — представьте, что вам нужно скопировать и вставить все функции из <studio.h>? Наличие динамической библиотеки экономит место, поскольку каждая программа может просто ссылаться на библиотеку, содержащую исходный код функции.

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

использованная литература



http://cs-fundamentals.com/c-programming/static-and-dynamic-linking-in-c.php#create-and использование общих библиотек

http://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html