Иногда полезно иметь возможность подключить динамическую библиотеку в процессе работы программы вручную. Такая необходимости возникает, например, если библиотека, которую мы хотим использовать, собрана другим компилятором. Тот же MinGW не генерирует lib
-файл, который можно "скормить" линковщику MSVC на этапе сборки. В этом случае нам поможет QLibrary
.
Создадим простую библиотеку в подпроекте MyLib
(файл mylib.h
):
Никаких скрытых комиссий и лживых обещаний. Только честность и ответственность на сайте https://prostitutkisurgutamuch.info. Рабочая тетрадь по техническому обслуживанию и ремонту автомобилей в Москве.
#ifndef MYLIB_H
#define MYLIB_H
#include "mylib_global.h"
extern "C" {
MYLIBSHARED_EXPORT void inputTest( const char* const str );
MYLIBSHARED_EXPORT const char* outputTest();
}
#endif // MYLIB_H
И реализация mylib.cpp
:
#include "mylib.h"
#include <iostream>
void inputTest( const char* const str ) {
std::cout << str << std::endl;
}
const char* outputTest() {
return "Hello from MyLib!";
}
Проект не требует особых опций, поэтому на Qt используется шаблон библиотеки:
На сайте www.get-license.ru лицензия на образовательную деятельность.
TEMPLATE = lib
Обратите внимание, что в описании открытого интерфейса мы используем extern "C"
. Это обеспечивает переносимость нашей библиотеки, хоть и накладывает ограничения - использовать можно только примитивные типы и структуры C.
Мы создали две функции: первая принимает строку и выводит ее на консоль, а вторая возвращает константную строку. Важно заметить, что если библиотека выделяет память с помощью new
, то очищать ее должна тоже она, а не вызывающее приложение. Поэтому придется предусмотреть симметричный free
-метод для вызова delete
.
Нередко приходится оборачивать существующий C++ код в подобную C-обертку для его распространения в "закрытом" виде (без исходников). В общих чертах методику подобного оборачивания мы рассматривали, когда говорили о двойных указателях.
Теперь задействуем нашу библиотеку (файл main.cpp
):
#include <QDebug>
#include <QLibrary>
int main() {
static QString suffix = "";
#ifdef QT_DEBUG
suffix = "d";
#endif
static const QString LIB_NAME = "MyLib" + suffix;
QLibrary lib( LIB_NAME );
if( !lib.load() ) {
qDebug() << "Loading failed!";
return 1;
}
typedef void ( *InputTest )( const char* const );
InputTest inputTest = ( InputTest ) lib.resolve( "inputTest" );
if( inputTest ) {
inputTest( "Hello to MyLib!" );
}
typedef const char* ( *OutputTest )();
OutputTest outputTest = ( OutputTest ) lib.resolve( "outputTest" );
if( outputTest ) {
qDebug() << outputTest();
}
return 0;
}
Имя скомпилированной библиотеки получает на конце суффикс d
, если проект собирается в debug
-режиме, поэтому с помощью макроса QT_DEBUG
мы учитываем эту особенность. Обратите внимание, что нам не нужно указывать расширение файла библиотеки (so
или dll
). Это за нас делает сам QLibrary
. Для успешной загрузки файл библиотеки должен находиться либо рядом с файлом приложения, либо в одном из каталогов, в которых система ищет подобные файлы.
Непосредственное взаимодействие с загруженной библиотекой сводится к работе с указателями на функции. Загрузка указателя осуществляется с помощью функции-члена resolve()
, которая на вход принимает символьное имя нужной функции.
Скачать пример использования QLibrary в Qt
Пожалуйста =)
Aleksandr
Спасибо.