Pull to refresh

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

C++ *

Введение


До начала работы с библиотекой Qt я программировал различные задачки на С++ в университете, а на работе использовал Delphi. И конечно же, в процессе работы создавались различные библиотеки. Создавались, можно сказать, с трудом. Не хватало в повседневной жизни тех плюсов, которые давало ООП. Всегда хотелось экспортировать из библиотек целые классы, причем делать это просто, быстро и беззаботно. При этом вопросы о создании библиотек на С++ и дальнейшем их использовании в проектах на Delphi или C возникали очень редко.

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

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


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

Большая часть изменений касается *.pro файла Вашей будущей библиотеки:
  1. # Мы создаем библиотеку
  2. # В указанную директорию относительно директории, в которой находится
  3. # pro-файл будут помещены бинарные файлы библиотеки.
  4. TEMPLATE = lib
  5. DESTDIR = dist
  6. # Версия библиотеки.
  7. VERSION = 1.0.0
  8. # Задаем имя нашей библиотеки
  9. TARGET = $$qtLibraryTarget(MyLibrary)
  10. # Указываем, что собирать надо release и debug версии библиотек
  11. CONFIG += build_all

О функции qtLibraryTarget


Функция $$qtLibraryTarget дополняет название нашей библиотеки номером версии и постфиксом типа сборки (“d” — в windows, “_debug” — в mac, в linux постфикса нет). То есть в после сборки в папке назначения мы увидим файлы (windows):
  • MyLibrary1.dll — release-сборка библиотеки. (Номер версии берется из старшего разряда, указанного в теге VERSION. Например, VERSION = 1.0.0, следует номер версии библиотеки будет равен 1)
  • MyLibraryd1.dll — debug-сборка библиотеки.

Правим код


Теперь необходимо настроить экспорт нашего кода из библиотек. Для этого создадим в новый заголовочный файл и назовем его, например, MyLibrary_global.h. Его содержимое должно быть таким (Creator создает этот файл автоматически при создании проекта динамической библиотеки):
  1. #ifndef MYLIBRARY_GLOBAL_H
  2. #define MYLIBRARY_GLOBAL_H
  3.  
  4. #include <QtCore/qglobal.h>
  5.  
  6. #if defined(MyLibrary_LIBRARY)
  7. #  define MyLibrary_EXPORT Q_DECL_EXPORT
  8. #else
  9. #  define MyLibrary_EXPORT Q_DECL_IMPORT
  10. #endif
  11.  
  12. #endif  /* MYLIBRARY_GLOBAL_H */

Добавим созданный файл в проект:
  1. HEADERS += MyLibrary_global.h
  2. # И допишем обязательную строчку с макросом экспорта:
  3. DEFINES += MyLibrary_LIBRARY

Экспорт классов и функций


И теперь самое главное. Во всех классах и функциях, которые должны быть видны снаружи библиотеки, необходимо дописать определенный ранее макрос MyLibrary_EXPORT (эти файлы будут заголовочными и должны поставляться вместе с бинарными файлами библиотеки). Например, мы хотим экспортировать класс:
  1. #include "MyLibrary_global.h"
  2. class MyLibrary_EXPORT ComputerManager: public QObject {
  3.     Q_OBJECT
  4. ...
  5. }
  6. // или функцию:
  7. MyLibrary_EXPORT QDebug operator<<(QDebug d, const MyObject &object);

О сборке библиотек в linux


Как уже было сказано, при сборке библиотеки в linux постфикс типа сборки не ставится (в этом можно убедиться, посмотрев реализацию этой функции qtLibraryTarget в исходниках qt). Но и это не беда, достаточно немного подправить строки в pro-файле:
  1. # Если операционная система из семейства unix
  2. unix: {
  3.         CONFIG (debug, debug|release) {
  4.                 # Такое название имеет debug-версия библиотеки
  5.                 TARGET = ComputerManagerd
  6.         } else {
  7.                 # А такое release-версия
  8.                 TARGET = ComputerManager
  9.         }
  10. } else {
  11.         TARGET = $$qtLibraryTarget(ComputerManager)
  12. }
  13. VERSION = 1.0.0
  14. # Первый параметр необходим для сборки #библиотеки в linux (qmake, make all),
  15. # второй для сборки под остальными ОС.
  16. CONFIG += debug_and_release build_all
  17. # Указываем папки для объектных файлов. Для unix-подобных ОС это критично.
  18. # Если этого не сделать, то будет собираться только release версия библиотеки,
  19. # либо только отладочная. Связано это с тем, что файлы будут замещать друг друга.
  20. CONFIG (debug, debug|release) {
  21.         OBJECTS_DIR = build/debug
  22. } else {
  23.         OBJECTS_DIR = build/release
  24. }
Эта часть pro-файла будет создавать одновременно динамические библиотеки в debug и release версиях на windows, linux, mac.

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


В pro-файле проекта необходимо дописать строки:
  1. # Подключаем заголовочные файлы библиотеки
  2. INCLUDEPATH += include/MyLibrary
  3. CONFIG(debug, debug|release) {
  4.     # Подключаем debug-версии библиотек для разных платформ
  5.     win32: LIBS += -Llib -lMyLibraryd1
  6.     unix: LIBS += -Llib -L. -lMyLibraryd -Wl,-rpath,lib -Wl,-rpath,.
  7. } else {
  8.     # Подключаем release-версии библиотек для разных платформ
  9.     win32: LIBS += -Llib -lMyLibrary1
  10.     unix: LIBS += -Llib -L. -lMyLibrary -Wl,-rpath,lib -Wl,-rpath,.
  11. }

При этом подразумевается, что в корне вашего проекта имеется две папки:
lib — Содержит бинарные файлы библиотеки. include — содержит папку MyLibrary со всеми заголовочными файлами библиотеки.

Заключение


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

Подсветка синтаксиса: Редактор Блогов от © SoftCoder.ru
Tags:
Hubs:
Total votes 15: ↑14 and ↓1 +13
Views 44K
Comments Comments 6