Cвоя библиотека my_library.a в языке Си для начинающих

Всем привет! Я Стас harrioho, учащийся Ярославского кампуса School 21. В нашем сообществе нет преподавателей, мы учимся сами и учим друг друга. В этой статье рассказываю, как при разработке на языке Си избежать дублирования кода, и вынести его в собственную библиотеку.

Заголовочный файл VS библиотека

Самым первым и самым очевидным способом избежать дублирования кода является применение собственного заголовочного файла: например my_library.h, и подключение его в свои проекты с помощью директивы #include. Но есть нюанс.

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

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

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

К программе на Си можно подключать статические(my_library.a, my_library.lib) и динамические(my_library.so, my_libraby.dll) библиотеки. Они обе предварительно скомпилированы, содержат в себе реализации функций.

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

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

Практика

Напишем с применением статической библиотеки простую программу, которая будет выводить в консоль “Hello world!”. Для этого декомпозируем программу на модули, и напишем их код:

my_library.h

void my_hello(void); void my_world(void);

main.c

#include “my_library.h” int main(void){ my_hello(); my_world(); return 0; }

my_hello.c

#include <stdio.h> #include “my_library.h” void my_hello(void){ printf(“Hello “); }

my_world.c

#include <stdio.h> #include “my_library.h” void my_world(void){ printf(“world!\n“); }

Теперь соберём реализацию функций my_hello и my_world в статическую библиотеку. Перед этим файлы Си нужно преобразовать в объектные файлы передав компилятору флаг -с:

gcc –c my_hello.c gcc –c my_wordld.c

Получаем два новых файла my_hello.o и my_world.o, из которых и будет состоять библиотека. Сборку произведём специальной утилитой ar (сокр. archiver):

ar crs my_library.a my_hello.o my_world.o

Здесь:
ar – вызываемая утилита
crs – три отдельных флага утилиты, написанных слитно. Значения флагов можно почитать в консоли man ar.

После того, как мы получили предварительно скомпилированную библиотеку, для чистоты эксперимента мы удалим исходные и объектные файлы my_hello и my_world, так что в нашем проекте останутся только my_library.h, my_library.a и main.c

rm my_hello.o my_hello.c my_world.o my_world.c

Скомпилируем исполняемую программу:

gcc main.c -o hello -L. my_library.a -Wall -Werror –Wextra

Здесь:
-o hello сообщает компилятору имя создаваемой программы
-L. в gcc флаг указывает путь до присоединяемой библиотеки или заголовочного файла. У нас файл лежит в одной директории с main, поэтому путь - точка
-Wall -Werror –Wextra используются для управления предупреждениями, которые компилятор выдает во время компиляции кода.

Итак, в директории с нашей программой появился новый исполняемый файл hello. Запустим его командой:

./hello

И увидим в консоли ожидаемое «Hello world!». Наша программа собрана и работает успешно.

Понравилась статья? Перешли её соседу слева и соседу справа. Всем лёгкого кода и peer-to-peer!

11
11
реклама
разместить
Начать дискуссию