Как сделать свою библиотеку

Добавил пользователь Дмитрий К.
Обновлено: 05.10.2024

На форуме возник вопрос, как создать динамическую библиотеку и правильно её подключить в сторонний проект. Периодически такие вопросы возникают, поэтому рассмотрим один вариант создание динамической библиотеки dll для Windows с использованием визардов стандартных в Qt Creator.

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

Создадим два проекта:

  1. QuiLib - это будет внешняя динамическая библиотека, которая будет содержать одно диалоговое окно. Данное диалоговое окно будет открываться в основном проекте.
  2. WithDynamicLibrary - проект, который будет использоваться как раз для подключения данной динамической библиотеки.

Шаг 1

Выберем в меню Qt Creator создание проекта и выберем тип нашего проекта. Это будет библиотека на C++.


Шаг 2

Пропишем название проекта и место его размещения


Шаг 3

Выберем комплекты для сборки проекта.

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

Я собираю данную библиотеку компилятором MSVC2017.


Шаг 4

Выбираем необходимые модули. Для нашей библиотеки хватит базового функционала.


Шаг 5

Дадим название классу библиотеки, который будет в нём использоваться. Название в данном случае будет такое же, как и название самой библиотеки. Но можно и поменять. Это не принципиально.


Шаг 6

Используете систему контроля версий? Так добавьте проект под контроль версий. Если нет, то ничего не делайте. И просто завершите создание библиотеки.


Шаг 7

Посмотрим на файлы проекта и немного модифицируем их.

Структура проекта


QuiLib.pro

В данном файле имеется информация о том, что это именно библиотека. Вот в данной строчке.

Вот полный код pro-файла

quilib_global.h

Хедер для определения дефайнов экспорта в библиотеке. Классы, которые будут помечены дефайном экспорта, будут доступны для использования вне библиотеки.

QuiLib.h

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

QuiLib.cpp

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

Шаг 8

Скомпилируем проект в Debug и Release версиях.

Вот например, что будет в каталоге release сборки библиотеки. Из тех файлов нам понадобятся только файлы QuiLib.dll и QuiLib.lib. Помимо этих файлов нужны ещё будут заголовочный файлы из самого проекта, но об этом немного позднее.


Шаг 9

Создание проекта, который будет использовать эту динамическую библиотеку. Процесс создания будет стандартный, через визард в Qt Creator. Нужно будет выбрать Приложение на Qt.

Добавить название проекта и место его размещения


Шаг 10

Указать комплект сборки.


Шаг 11

Введём название класса главного окна приложения, а также укажем от какого класса наследоваться. Я выбрал QWidget.


Шаг 12

Снова выбор системы контроля версий и завершение процесса создания проекта.


Шаг 13

Структура проекта


В каталоге данного проекта создадим каталог QuiLib , в который поместим каталоги debug, release, include.

В данных каталогах будут содержаться скомпилированные библиотеки QuiLib.dll и QuiLib.lib соответственно отладочной версии и выпускаемой версии. В каталоге include будут заголовочные файлы QuiLib.h и quilib_global.h.

То есть мы представили ту ситуацию, в которой мы кому-то передали скомпилированную библиотеку, чтобы он мог её подключить и использовать.

Шаг 14

Добавляем библиотеку в проект с помощью визарда. Можно конечно и вручную всё прописать, но если сомневаетесь в своих силах, а это так и есть, иначе не читали бы эту статью, то используем визард.


Шаг 15

Мы знаем, что библиотека внешняя


Шаг 16

А также, что будем использовать её только для Windows. Здесь настроено, что файлы Debug и Release версий находятся в разных каталогах без всяких префиксов отладочных библиотек. Я их просто не настраивал. Достаточно указать одну из .lib * библиотек либо в debug, либо release каталоге. Путь к другой версии будет добавлен автоматически. Также нужно указать каталог, в котором располагаются заголовочные файлы. Традиционно это include** каталог.


Шаг 17


Шаг 18

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

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

WithDynamicLibrary.pro

Это самые последние строки в данном файле.

Widget.ui

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


Widget.h

Пропишем слот, для обработки клика кнопки.

Widget.cpp

А теперь обработаем клик кнопки и вызовем диалоговое окно из внешней библиотеки.

Заметьте, что вызывать диалоговое окно нужно обязательно методом exec() чтобы запустилась внутренняя петля диалога, которая будет ожидать событий. Иначе диалог сразу закроется, поскольку слот отработает, а диалог в данном случае создан на стеке метода и по завершению метода диалог уничтожится. А метод exec() завершится только тогда, когда произойдёт соответствующее событие, которое закроет диалог.

Результат


Рекомендуем хостинг TIMEWEB

Рекомендуем хостинг TIMEWEB

Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.


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

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

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

Наше портфолио более 10 000 проектов

стиль Минимализм

стиль Минимализм

стиль Минимализм

стиль Минимализм

стиль Минимализм

стиль Минимализм

стиль Современная классика

стиль Современная классика

стиль Современная классика

стиль Современная классика

стиль Современная классика

стиль Современная классика

Скандинавский стиль

Скандинавский стиль

Скандинавский стиль

Скандинавский стиль

Скандинавский стиль

Скандинавский стиль

стиль Минимализм

стиль Минимализм

стиль Минимализм

стиль Минимализм

стиль Минимализм

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

1. Библиотека в коридоре

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

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

Рассчитайте точную стоимость ремонта на онлайн-калькуляторе

и бесплатно получите подробную смету на ремонт

Если габариты коридора позволяют, стеллажи или полки с книгами можно разместить по обе стены. Более узкий коридор потребует к себе индивидуального подхода: необходимо понять, не станут ли критичными те 25—30 сантиметров (средняя ширина книги), которые займут полки.

2. Читальный зал на подоконнике

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

Когда габариты подоконника не позволяют использовать его как импровизированный диван, место под окном подойдет для хранения книг.

3. Два в одном: библиотека и элемент декора

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

Среди недостатков, пожалуй, только ограниченная вместимость таких полок.

4. Библиотека-лоджия

Оборудованную лоджию вполне можно превратить в домашнюю библиотеку или даже полноценный кабинет.

5. Книжный шкаф вокруг двери или окна

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

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

Кстати, реализовать эту идею можно не вокруг окна, а в одном из свободных углов.

6. Решение для тех, у кого очень много книг.

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

7. … и тех, у кого их еще больше!

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

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

9. Букенды

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

10. Домашняя библиотека по-скандинавски

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

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

Фото № 4: Домашняя библиотека: как оформить, где найти место — 12 отличных идей

Фото: kidskunst.info

11. Все в одном

12. Скрытая мини-библиотека

Если в интерьер никак не вписываются высокие стеллажи с книгами, их всегда можно скрыть при помощи текстиля: как вариант — книжные полки можно завесить шторами в тон цветовой гамме помещения.

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

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

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

При компиляции программы библиотеки подключаются линковщиком, который вызывается gcc. Если программе требуются только стандартные библиотеки, то дополнительных параметров линковщику передавать не надо (есть исключения). Он "знает", где стандартные библиотеки находятся, и подключит их автоматически. Во всех остальных случаях при компиляции программы требуется указать имя библиотеки и ее местоположение.

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

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

Пример создания библиотеки

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

В итоге, когда все будет сделано, схема каталогов и файлов будет выглядеть так:

Пусть каталоги library и project находятся в одном общем каталоге, например, домашнем каталоге пользователя. Каталог library содержит каталог source с файлами исходных кодов библиотеки. Также в library будут находиться заголовочный файл (содержащий описания функций библиотеки), статическая (libmy1.a) и динамическая (libmy2.so) библиотеки. Каталог project будет содержать файлы исходных кодов проекта и заголовочный файл с описанием функций проекта. Также после компиляции с подключением библиотеки здесь будет располагаться исполняемый файл проекта.
В операционных системах GNU/Linux имена файлов библиотек должны иметь префикс "lib", статические библиотеки - расширение *.a, динамические - *.so.

Для компиляции проекта достаточно иметь только одну библиотеку: статическую или динамическую. В образовательных целях мы получим обе и сначала скомпилируем проект со статической библиотекой, потом — с динамической. Статическая и динамическая "разновидности" одной библиотеки по-идее должны называться одинаково (различаются только расширения). Поскольку у нас обе библиотеки будут находиться в одном каталоге, то чтобы быть уверенными, что при компиляции проекта мы используем ту, которую хотим, их названия различны (libmy1 и libmy2).

Исходный код библиотеки

В файле figure.c содержатся две функции — rect() и diagonals() . Первая принимает в качестве аргументов символ и два числа и "рисует" на экране с помощью указанного символа прямоугольник заданной ширины и высоты. Вторая функция выводит на экране две диагонали квадрата ("рисует" крестик).

В файле text.c определена единственная функция, принимающая указатель на символ строки. Функция выводит на экране звездочки в количестве, соответствующем длине указанной строки.

Заголовочный файл можно создать в каталоге source, но мы лучше сохраним его там, где будут библиотеки. В данном случае это на уровень выше (каталог library). Тем самым как бы подчеркивается, что файлы исходных кодов после создания из них библиотеки вообще не нужны пользователям библиотек, они нужны лишь разработчику библиотеки. А вот заголовочный файл библиотеки требуется для ее правильного использования.

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

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

Все действия, которые описаны ниже выполняются в каталоге library (т.е. туда надо перейти командой cd). Просмотр содержимого каталога выполняется с помощью команды ls или ls -l.

Получаем объектные файлы:

В итоге в каталоге library должно наблюдаться следующее:

Далее используем утилиту ar для создания статической библиотеки:

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

Объектные файлы нам не нужны, поэтому их можно удалить:

В итоге содержимое каталога library должно выглядеть так:

, где libmy1.a — это статическая библиотека.

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

Объектные файлы для динамической библиотеки компилируются особым образом. Они должны содержать так называемый позиционно-независимый код (position independent code). Наличие такого кода позволяет библиотеке подключаться к программе, когда последняя загружается в память. Это связано с тем, что библиотека и программа не являются единой программой, а значит как угодно могут располагаться в памяти относительно друг друга. Компиляция объектных файлов для динамической библиотеки должна выполняться с опцией -fPIC компилятора gcc:

В отличие от статической библиотеки динамическую создают при помощи gcc указав опцию -shared:

Использованные объектные файлы можно удалить:

В итоге содержимое каталога library:

Использование библиотеки в программе

Исходный код программы

Теперь в каталоге project (который у нас находится на одном уровне файловой иерархии с library) создадим файлы проекта, который будет использовать созданную библиотеку. Поскольку сама программа будет состоять не из одного файла, то придется здесь также создать заголовочный файл.

Функция data() запрашивает у пользователя данные, помещая их в массив strs. Далее вызывает библиотечную функцию diagonals() , которая выводит на экране "крестик". После этого на каждой итерации цикла вызывается библиотечная функция text() , которой передается очередной элемент массива; функция text() выводит на экране звездочки в количестве равному длине переданной через указатель строки.

Обратите внимание на то, как подключается заголовочный файл библиотеки: через относительный адрес. Две точки обозначают переход в каталог на уровень выше, т.е. родительский по отношению к project, после чего путь продолжается во вложенный в родительский каталог library. Можно было бы указать абсолютный путь, например, "/home/pl/c/les22/library/mylib.h". Однако при перемещении каталогов библиотеки и программы на другой компьютер или в другой каталог адрес был бы уже не верным. В случае с относительным адресом требуется лишь сохранять расположение каталогов project и library относительно друг друга.

Здесь два раза вызывается библиотечная функция rect() и один раз функция data() из другого файла проекта. Чтобы сообщить функции main() прототип data() также подключается заголовочный файл проекта.

Файл project.h содержит всего одну строчку:

Из обоих файлов проекта с исходным кодом надо получить объектные файлы для объединения их потом с файлом библиотеки. Сначала мы получим исполняемый файл, содержащий статическую библиотеку, потом — связанный с динамической библиотекой. Однако с какой бы библиотекой мы не компоновали объектные файлы проекта, компилируются они как для статической, так и динамической библиотеки одинаково:

При этом не забудьте сделать каталог project текущим!

Компиляция проекта со статической библиотекой

Теперь в каталоге project есть два объектных файла: main.o и data.o. Их надо скомпилировать в исполняемый файл project, объединив со статической библиотекой libmy1.a. Делается это с помощью такой команды:

Начало команды должно быть понятно: опция -o указывает на то, что компилируется исполняемый файл project из объектных файлов.

Помимо объектных файлов проекта в компиляции участвует и библиотека. Об этом свидетельствует вторая часть команды: -L../library -lmy1. Здесь опция -L указывает на адрес каталога, где находится библиотека, он и следует сразу за ней. После опции -l записывается имя библиотеки, при этом префикс lib и суффикс (неважно .a или .so) усекаются. Обратите внимание, что после данных опций пробел не ставится.

Опцию -L можно не указывать, если библиотека располагается в стандартных для данной системы каталогах для библиотек. Например, в GNU/Linux это /lib/, /urs/lib/ и др.

Запустив исполняемый файл project и выполнив программу, мы увидим на экране примерно следующее:

Посмотрим размер файла project:

Его размер равен 8698 байт.

Компиляция проекта с динамической библиотекой

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

Здесь в отличии от команды компиляции со статической библиотеки добавлены опции для линковщика: -Wl,-rpath. /library/. -Wl - это обращение к линковщику, -rpath - опция линковщика, ../library/ - значение опции. Получается, что в команде мы два раза указываем местоположение библиотеки: один раз с опцией -L, а второй раз с опцией -rpath. Видимо для того, чтобы понять, почему так следует делать, потребуется более основательно изучить процесс компиляции и компоновки программ на языке C.

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

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

Размер исполняемого файла проекта, связанного с динамической библиотекой, получился равным 8544 байта. Это немного меньше, чем при компиляции проекта со статической библиотекой. Если посмотреть на размеры библиотек:

, то видно, что динамическая больше статической, хотя исполняемый файл проекта со статической библиотекой больше. Это доказывает, что в исполняемом файле, связанном с динамической библиотекой, присутствует лишь ссылка на нее.

Arduino довольно сильно основан на C ++ (язык программирования). Этот язык основан на вещах, называемых заголовками, функциями и библиотеками. Эти вещи, фактически, переносятся и используются в Arduino. Как правило библиотеки включаются в самое начало вашего кода и используются для упрощения кода всего проекта, например:

Большинство нужных библиотек вы можете найти на нашем сайте в разделе Библиотеки. В этом уроке мы продемонстрируем, как создать собственную библиотеку для Ардуино.

Шаг 1. Программное обеспечение

Вы также можете попробовать что-то вроде Notepad++, VSCode. Мы обычно используем Sublime Text 3 для программирования.

Шаг 2. Код Arduino

Это базовый эскиз Blink для включения встроенного светодиода:

Этот код не очень сложный, и ему вообще не нужна библиотека. Однако, ради демонстрации, мы все равно сделаем это.

Шаг 3. Создание библиотеки


Код для .h файла:

Код для .cpp файла:

Теперь сохраните оба файла и выйдите.

Шаг 4. Встраивание библиотеки


Закройте Arduino IDE и снова откройте её. Перейдите в:

Sketch > Include Library / Включить Библиотеку

Прокрутите страницу вниз до "Contributed Libraries". Вы должны увидеть одну из них под названием MyLibrary. Нажмите на нее, и вы увидите:

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

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

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

Если вы хотите, чтобы ваша библиотека делала больше, чем просто мигала светодиодом, все, что вам нужно сделать, это отредактировать два файла, которые мы создали ранее. Если вы заинтересованы в создании более сложных библиотек, вам может помочь изучение C++.

Читайте также: