How to create a library with Qt and use it in an application/ru: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
 
(fix a lot of ''' that was insted of *)
 
(8 intermediate revisions by 3 users not shown)
Line 1: Line 1:
'''Русский''' [[How to create a library with Qt and use it in an application|English]] [[How to create a library with Qt and use it in an application Spanish|Español]]
{{Cleanup | reason=Auto-imported from ExpressionEngine.}}


=Введение=
'''Русский''' [[How_to_create_a_library_with_Qt_and_use_it_in_an_application|English]] [[How_to_create_a_library_with_Qt_and_use_it_in_an_application_Spanish|Español]]
[[Category:HowTo]]
[[Category:Developing_with_Qt::General]]
[[Category:Tutorial]]


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


==Создание разделяемой библиотеки==
= Введение =


При создании совместно используемой библиотеки, которую бы вы хотели присоединить, необходимо удостовериться, что символы, которые будут использованы за пределами библиотеки, будут должным образом экспортироваться после создания библиотеки. В последствии они будут импортированы при присоединении. Это может быть сделано, с помощбю [http://doc.qt.io/qt-4.8/qtglobal.html#Q_DECL_EXPORT Q_DECL_EXPORT] ''[qt.io]'' и [http://doc.qt.io/qt-4.8/qtglobal.html#Q_DECL_IMPORT Q_DECL_IMPORT] ''[qt.io]'' как показано в следующем примере:
Это руководство иллюстрирует разные подходы к созданию и применению пользовательских библиотек в приложении на Windows. Первая часть объясняет, как создать совместно используемую библиотеку и как присоединить ее к приложению. Вторая часть - о создании и использовании статической библиотеки.


'''test.h'''<br />
== Создание разделяемой библиотеки ==


'''test.cpp'''<br />
При создании совместно используемой библиотеки, которую вы бы хотели присоединить, необходимо удостовериться, что символы, которые будут использованы за пределами библиотеки, будут должным образом экспортироваться после создания библиотеки. Впоследствии они будут импортированы при присоединении. Это может быть сделано с помощью [http://doc.qt.io/qt-4.8/qtglobal.html#Q_DECL_EXPORT Q_DECL_EXPORT ] и [http://doc.qt.io/qt-4.8/qtglobal.html#Q_DECL_IMPORT Q_DECL_IMPORT] как показано в следующем примере:


'''test.pro'''<br />
'''test.h'''
<code>
#include <QtGui>


См. также документацию описывающую [http://doc.qt.io/qt-4.8/sharedlibrary.html Создание Совместно используемых Библиотек] ''[qt.io]''.
#if defined TEST
#define TEST_COMMON_DLLSPEC Q_DECL_EXPORT
#else
#define TEST_COMMON_DLLSPEC Q_DECL_IMPORT
#endif


===Присоединение разделяемой библиотеки к приложению===
class TEST_COMMON_DLLSPEC Widget : public QWidget
{
Q_OBJECT
public:
Widget();
};


</code>
'''test.cpp'''
<code>
#include <QtGui>
#include "test.h"
Widget::Widget() : QWidget()
{}
</code>
'''test.pro'''
<code>TEMPLATE = lib
# Input
SOURCES += test.cpp
HEADERS += test.h
DEFINES += TEST</code>
См. также документацию описывающую [http://doc.qt.io/qt-4.8/sharedlibrary.html Создание Совместно используемых Библиотек].
=== Присоединение разделяемой библиотеки к приложению ===
Чтобы использовать разделяемую библиотеку в приложении, вы можете включить ее заголовок в ваш код и использовать доступные методы. Скомпилируйте и соберите с.lib файл. Во время выполнения будет загружена dll, у которой имеется реализация.
Чтобы использовать разделяемую библиотеку в приложении, вы можете включить ее заголовок в ваш код и использовать доступные методы. Скомпилируйте и соберите с.lib файл. Во время выполнения будет загружена dll, у которой имеется реализация.


Для успешной сборки, в файле .pro необходимо сообщить приложению, где найти заголовки и библиотеки. [http://doc.qt.io/qt-4.8/qmake-variable-reference.html#includepath <span class="caps">INCLUDEPATH</span>] ''[qt.io]'' должен указывать на каталог, где находятся заголовки, и [http://doc.qt.io/qt-4.8/qmake-variable-reference.html#libs <span class="caps">LIBS</span>] ''[qt.io]'' переменная должна указывать на каталог с .lib файлом. Кроме того, необходимо удостовериться, что .dll будет находиться в указанном месте или помещена в каталог приложения или путь к ней описан в переменной <span class="caps">PATH</span>.
Для успешной сборки, в файле .pro необходимо сообщить приложению, где найти заголовки и библиотеки. [http://doc.qt.io/qt-4.8/qmake-variable-reference.html#includepath INCLUDEPATH] должен указывать на каталог, где находятся заголовки, и [http://doc.qt.io/qt-4.8/qmake-variable-reference.html#libs LIBS] переменная должна указывать на каталог с .lib файлом. Кроме того, необходимо удостовериться, что .dll будет находиться в указанном месте или помещена в каталог приложения или путь к ней описан в переменной PATH.


Для примера:
Для примера:


'''loadTestLib.pro'''<br />
'''loadTestLib.pro'''
<code>
TEMPLATE = app
TARGET =
DEPENDPATH += . ../testLib
INCLUDEPATH += ../testLib
LIBS += -L../testLib/debug -ltestLib
# Input
SOURCES += main.cpp
</code>
 
'''main.cpp'''
<code>
#include <QtGui>
#include "test.h"


'''main.cpp'''<br />
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.resize(100,100);
w.show();
return a.exec();
}


===Использование QLibrary, для загрузки разделяемых библиотек===


[http://doc.qt.io/qt-4.8/qlibrary.html#details QLibrary] ''[qt.io]'' может использоваться для загрузки разделяемых библиотек в момент выполнения. В этом случае достаточно иметь доступ только к .dll, доступ к заголовкам и .lib файлу(ам) не требуется.
</code>


Следующий пример показывает, как установить библиотеку для использования с QLibrary. Для разрешения имен функций, они должны быть экспортированы из библиотеки как C функции (т.е. без искажения имени). Это означает, что функции должны быть обернуты в блок extern “C”, в случае если библиотека скомпилирована компилятором C++.
=== Использование QLibrary, для загрузки разделяемых библиотек ===
[http://doc.qt.io/qt-4.8/qlibrary.html#details QLibrary] может использоваться для загрузки разделяемых библиотек в момент выполнения. В этом случае достаточно иметь доступ только к .dll, доступ к заголовкам и .lib файлу(ам) не требуется.


Вот как делается это на Windows, также необходимо явно экспортировать функцию для использования <span class="caps">DLL</span> [http://doc.qt.io/qt-4.8/qtglobal.html#Q_DECL_EXPORT Q_DECL_EXPORT] ''[qt.io]'' и [http://doc.qt.io/qt-4.8/qtglobal.html#Q_DECL_IMPORT Q_DECL_IMPORT] ''[qt.io]''
Следующий пример показывает, как установить библиотеку для использования с QLibrary. Для разрешения имен функций, они должны быть экспортированы из библиотеки как C функции (т.е. без искажения имени). Это означает, что функции должны быть обернуты в блок extern "C", в случае если библиотека скомпилирована компилятором C.


'''qlibraryLibrary.pro'''<br />
Вот как делается это на Windows, также необходимо явно экспортировать функцию для использования DLL [http://doc.qt.io/qt-4.8/qtglobal.html#Q_DECL_EXPORT Q_DECL_EXPORT] и [http://doc.qt.io/qt-4.8/qtglobal.html#Q_DECL_IMPORT Q_DECL_IMPORT]


'''widget.h'''<br />
'''qlibraryLibrary.pro'''
<code>
TEMPLATE = lib
HEADERS += widget.h
SOURCES += widget.cpp
DEFINES += TEST
</code>


'''widget.cpp'''<br />
'''widget.h'''
<code>
#include <QtGui>


===Загрузка библиотеки, используя QLibrary===
#if defined TEST
#define TEST_COMMON_DLLSPEC Q_DECL_EXPORT
#else
#define TEST_COMMON_DLLSPEC Q_DECL_IMPORT
#endif


Чтобы загрузить библиотеку, используя QLibrary, можете просто передать .dll в конструктор QLibrary. Удостоверьтесь, что .dll доступна в каталоге приложения или в переменной <span class="caps">PATH</span>. Для того чтобы воспользоваться функциями библиотеки в приложении, вы должны разрешить их использование [http://doc.qt.io/qt-4.8/qlibrary.html#resolve QLibrary::resolve()] ''[qt.io]''.
extern "C" TEST_COMMON_DLLSPEC QWidget* createWidget1();


Следующий пример загружает выше-созданную библиотеку, и использует одну из ее функций, для создания и отображения виджета.
</code>


==Создание статической библиотеки==
'''widget.cpp'''
<code>
#include <QtGui>
#include "widget.h"


При создании статической библиотеки необходимо определить опцию staticlib [http://doc.qt.io/qt-4.8/qmake-variable-reference.html#config <span class="caps">CONFIG</span>] ''[qt.io]'' в .pro файле. В отличие от примера разделяемой библиотеки, в .h файле не требуется устанавливать никаких специальных символов для экспорта и импорта, потому как библиотека будет встроена в приложение, например:
QWidget* createWidget1()
{
QWidget *wid = new QWidget();
wid->resize(100,100);
return wid;
}


'''test.pro'''<br />
</code>


===Использование статической библиотеки в приложении===
=== Загрузка библиотеки, используя QLibrary ===
Чтобы загрузить библиотеку, используя QLibrary, можете просто передать .dll в конструктор QLibrary. Удостоверьтесь, что .dll доступна в каталоге приложения или в переменной PATH. Для того чтобы воспользоваться функциями библиотеки в приложении, вы должны разрешить их использование [http://doc.qt.io/qt-4.8/qlibrary.html#resolve QLibrary::resolve()].


Подобно тому, как мы сделали это при загрузке разделяемой библиотеки, необходимо описать [http://doc.qt.io/qt-4.8/qmake-variable-reference.html#includepath <span class="caps">INCLUDEPATH</span>] ''[qt.io]'', чтобы указать на каталог, где установлены заголовки и [http://doc.qt.io/qt-4.8/qmake-variable-reference.html#libs <span class="caps">LIBS</span>] ''[qt.io]'' переменную, чтобы указать на .lib файл, например:
Следующий пример загружает выше-созданную библиотеку, и использует одну из ее функций для создания и отображения виджета.


'''useStaticLib.pro'''<br />
<code>
#include <QtGui>


'''main.cpp'''<br />
int main(int argc, charargv)
{
QApplication app(argc, argv);
QLibrary library("qlibraryLibrary.dll");
if (!library.load())
qDebug() << library.errorString();
if (library.load())
qDebug() << "library loaded";


==Какой подход выбрать==
typedef QWidget *(*CreateWidgetFunction)(void);
CreateWidgetFunction cwf = (CreateWidgetFunction)library.resolve("createWidget1");
if (cwf) {
QWidget* wid = cwf();
if (wid)
wid->show();
} else {
qDebug() << "Could not show widget from the loaded library";
}
return app.exec();
}
</code>
 
== Создание статической библиотеки ==
 
При создании статической библиотеки необходимо определить опцию staticlib [http://doc.qt.io/qt-4.8/qmake-variable-reference.html#config CONFIG ] в .pro файле. В отличие от примера разделяемой библиотеки, в .h файле не требуется устанавливать никаких специальных символов для экспорта и импорта, потому как библиотека будет встроена в приложение, например:
 
'''test.pro'''
<code>
TEMPLATE = lib
CONFIG+= staticlib
# Input
HEADERS += test.h
SOURCES += test.cpp
</code>
 
=== Использование статической библиотеки в приложении ===
 
Подобно тому, как мы сделали это при загрузке разделяемой библиотеки, необходимо описать [http://doc.qt.io/qt-4.8/qmake-variable-reference.html#includepath INCLUDEPATH], чтобы указать на каталог, где установлены заголовки и [http://doc.qt.io/qt-4.8/qmake-variable-reference.html#libs LIBS] переменную, чтобы указать на .lib файл, например:
 
'''useStaticLib.pro'''
<code>
TEMPLATE = app
TARGET =
CONFIG+= console
# Input
SOURCES += main.cpp
INCLUDEPATH += ../staticLibrary
LIBS+= -L../staticLibrary/debug -lstaticLibrary
 
</code>
 
'''main.cpp'''
<code>
#include <QtGui>
#include "test.h"
 
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.resize(100,100);
w.show();
return a.exec();
}
</code>
 
== Какой подход выбрать ==


Принятие решения о том, какой подход выбрать, зависит от Ваших потребностей.
Принятие решения о том, какой подход выбрать, зависит от Ваших потребностей.
Line 70: Line 211:


Статическое подключение позволяет создать автономно исполняемую программу. Преимущество состоит в том, что для работы программы вам необходимо будет установить только несколько файлов. Недостаток в том, что исполняемые программы большие.
Статическое подключение позволяет создать автономно исполняемую программу. Преимущество состоит в том, что для работы программы вам необходимо будет установить только несколько файлов. Недостаток в том, что исполняемые программы большие.
См. [http://doc-snapshot.qt.io/4.8/deployment.html Документацию развертывания] ''[doc-snapshot.qt.io]'' для детального ознакомления о разделяемых и статических сборках.
===Categories:===
* [[:Category:Developing with Qt|Developing_with_Qt]]
** [[:Category:Developing with Qt::General|General]]
* [[:Category:HowTo|HowTo]]
* [[:Category:Tutorial|Tutorial]]

Latest revision as of 13:03, 4 January 2017

This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine.
Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean.

Русский English Español


Введение

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

Создание разделяемой библиотеки

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

test.h

#include <QtGui>

#if defined TEST
#define TEST_COMMON_DLLSPEC Q_DECL_EXPORT
#else
#define TEST_COMMON_DLLSPEC Q_DECL_IMPORT
#endif

class TEST_COMMON_DLLSPEC Widget : public QWidget
{
 Q_OBJECT
public:
 Widget();
};

test.cpp

#include <QtGui>
#include "test.h"

Widget::Widget() : QWidget()
{}

test.pro

TEMPLATE = lib
# Input
SOURCES += test.cpp
HEADERS += test.h
DEFINES += TEST

См. также документацию описывающую Создание Совместно используемых Библиотек.

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

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

Для успешной сборки, в файле .pro необходимо сообщить приложению, где найти заголовки и библиотеки. INCLUDEPATH должен указывать на каталог, где находятся заголовки, и LIBS переменная должна указывать на каталог с .lib файлом. Кроме того, необходимо удостовериться, что .dll будет находиться в указанном месте или помещена в каталог приложения или путь к ней описан в переменной PATH.

Для примера:

loadTestLib.pro

TEMPLATE = app
TARGET =
DEPENDPATH += . ../testLib
INCLUDEPATH += ../testLib
LIBS += -L../testLib/debug -ltestLib
# Input
SOURCES += main.cpp

main.cpp

#include <QtGui>
#include "test.h"

int main(int argc, char *argv[])
{
 QApplication a(argc, argv);
 Widget w;
 w.resize(100,100);
 w.show();
 return a.exec();
}

Использование QLibrary, для загрузки разделяемых библиотек

QLibrary может использоваться для загрузки разделяемых библиотек в момент выполнения. В этом случае достаточно иметь доступ только к .dll, доступ к заголовкам и .lib файлу(ам) не требуется.

Следующий пример показывает, как установить библиотеку для использования с QLibrary. Для разрешения имен функций, они должны быть экспортированы из библиотеки как C функции (т.е. без искажения имени). Это означает, что функции должны быть обернуты в блок extern "C", в случае если библиотека скомпилирована компилятором C.

Вот как делается это на Windows, также необходимо явно экспортировать функцию для использования DLL Q_DECL_EXPORT и Q_DECL_IMPORT

qlibraryLibrary.pro

TEMPLATE = lib
HEADERS += widget.h
SOURCES += widget.cpp
DEFINES += TEST

widget.h

#include <QtGui>

#if defined TEST
#define TEST_COMMON_DLLSPEC Q_DECL_EXPORT
#else
#define TEST_COMMON_DLLSPEC Q_DECL_IMPORT
#endif

extern "C" TEST_COMMON_DLLSPEC QWidget* createWidget1();

widget.cpp

#include <QtGui>
#include "widget.h"

QWidget* createWidget1()
{
 QWidget *wid = new QWidget();
 wid->resize(100,100);
 return wid;
}

Загрузка библиотеки, используя QLibrary

Чтобы загрузить библиотеку, используя QLibrary, можете просто передать .dll в конструктор QLibrary. Удостоверьтесь, что .dll доступна в каталоге приложения или в переменной PATH. Для того чтобы воспользоваться функциями библиотеки в приложении, вы должны разрешить их использование QLibrary::resolve().

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

#include <QtGui>

int main(int argc, charargv)
{
 QApplication app(argc, argv);
 QLibrary library("qlibraryLibrary.dll");
 if (!library.load())
 qDebug() << library.errorString();
 if (library.load())
 qDebug() << "library loaded";

 typedef QWidget *(*CreateWidgetFunction)(void);
 CreateWidgetFunction cwf = (CreateWidgetFunction)library.resolve("createWidget1");
 if (cwf) {
 QWidget* wid = cwf();
 if (wid)
 wid->show();
 } else {
 qDebug() << "Could not show widget from the loaded library";
 }
 return app.exec();
}

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

При создании статической библиотеки необходимо определить опцию staticlib CONFIG в .pro файле. В отличие от примера разделяемой библиотеки, в .h файле не требуется устанавливать никаких специальных символов для экспорта и импорта, потому как библиотека будет встроена в приложение, например:

test.pro

TEMPLATE = lib
CONFIG+= staticlib
# Input
HEADERS += test.h
SOURCES += test.cpp

Использование статической библиотеки в приложении

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

useStaticLib.pro

TEMPLATE = app
TARGET =
CONFIG+= console
# Input
SOURCES += main.cpp
INCLUDEPATH += ../staticLibrary
LIBS+= -L../staticLibrary/debug -lstaticLibrary

main.cpp

#include <QtGui>
#include "test.h"

int main(int argc, char *argv[])
{
 QApplication a(argc, argv);
 Widget w;
 w.resize(100,100);
 w.show();
 return a.exec();
}

Какой подход выбрать

Принятие решения о том, какой подход выбрать, зависит от Ваших потребностей.

При создании разделяемой библиотеки потребуется установить ее в целевой системе вместе с приложением. Преимущество: приложения собранные на разделяемых библиотеках, маленькие. Это независит от того, что используется для загрузки .dll, QLibrary или просто стандартное подключение. Важно, имеете ли вы доступ к заголовочным и .lib файлам или нет. Если доступа не имеете, тогда QLibrary -ваш выбор. Недостаток в том, что при отсутствии разделяемой библиотеки в системе приложение работать не будет.

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