IT Notes

QLibrary: Пример использования

Иногда полезно иметь возможность подключить динамическую библиотеку в процессе работы программы вручную. Такая необходимости возникает, например, если библиотека, которую мы хотим использовать, собрана другим компилятором. Тот же MinGW не генерирует lib-файл, который можно "скормить" линковщику MSVC на этапе сборки. В этом случае нам поможет QLibrary.

Реализация библиотеки

Создадим простую библиотеку в подпроекте MyLib (файл mylib.h):

#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 используется шаблон библиотеки:

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

Понравилась статья?
Не забудь поделиться ей с друзьями!
Реклама

Похожие публикации

Комментарии

Спасибо.

Пожалуйста =)

RSS RSS-рассылка

Популярное