「Qtの基礎 - ライブラリ」の版間の差分
134行目: | 134行目: | ||
==== 動的ライブラリの明示的リンク ==== | ==== 動的ライブラリの明示的リンク ==== | ||
Qtには、動的ライブラリの関数を簡単に使用するために、QLibraryクラスが用意されている。<br> | Qtには、動的ライブラリの関数を簡単に使用するために、QLibraryクラスが用意されている。<br> | ||
<br> | |||
明示的リンクを使用して、動的ライブラリの関数を呼び出す手順は、以下の通りである。<br> | |||
# 動的ライブラリの関数において、C言語のグローバル関数として定義する。 | |||
# 動的ライブラリを生成する。 | |||
# 動的ライブラリを呼び出す側の実行ファイルと同じディレクトリに、動的ライブラリを配置する。 | |||
# QLibraryクラスを使用して、動的ライブラリの関数を呼び出す。 | |||
<br> | <br> | ||
以下の構成を持つ2つのプロジェクトを作成したとする。<br> | 以下の構成を持つ2つのプロジェクトを作成したとする。<br> | ||
* プロジェクト構成 | * プロジェクト構成 | ||
* | ** 動的ライブラリ | ||
*: Utils | **: Utils | ||
* 実行ファイル | ** 実行ファイル | ||
*: Moc | **: Moc | ||
<br> | <br> | ||
まず、Utilsプロジェクトにおいて、関数のみを定義したUtils.cppファイルを作成する。<br> | まず、Utilsプロジェクトにおいて、関数のみを定義したUtils.cppファイルを作成する。<br> | ||
<syntaxhighlight lang="c++"> | |||
// Utils_global.h | |||
#ifndef UTILS_GLOBAL_H | |||
#define UTILS_GLOBAL_H | |||
#include <QtCore/qglobal.h> | |||
#ifdef Q_OS_WIN // Windows | |||
#if defined(UTILS_LIBRARY) | |||
#define UTILS_EXPORT __declspec(dllexport) | |||
#else | |||
#define UTILS_EXPORT | |||
#endif | |||
#elif Q_OS_LINUX // Linux | |||
#if defined(UTILS_LIBRARY) | |||
#define UTILS_EXPORT Q_DECL_EXPORT | |||
#else | |||
#define UTILS_EXPORT Q_DECL_IMPORT | |||
#endif | |||
#endif | |||
#endif // LIBDIALOG_GLOBAL_H | |||
</syntaxhighlight> | |||
<br> | |||
<syntaxhighlight lang="c++"> | <syntaxhighlight lang="c++"> | ||
// Utils.cpp | // Utils.cpp | ||
149行目: | 180行目: | ||
#include <iostream> | #include <iostream> | ||
#ifdef Q_OS_WIN | //#ifdef Q_OS_WIN | ||
#define | // #define UTILS_EXPORT __declspec(dllexport) | ||
#else | //#else | ||
#define | // #define UTILS_EXPORT | ||
#endif | //#endif | ||
extern "C" | extern "C" UTILS_EXPORT void SampleHello(int count) | ||
{ | { | ||
while(--count) | while(--count) |
2021年1月31日 (日) 19:36時点における版
概要
Qt Creatorにおいて、静的ライブラリおよび動的ライブラリを作成して、他のQtプロジェクトにリンクする手順を記載する。
静的ライブラリ
静的ライブラリの作成
- QT Creatorのメイン画面から、[ファイル]メニューバー - [ファイル / プロジェクトの新規作成]を選択する。
- [新しいファイルまたはプロジェクト]画面左にある[ライブラリ]から[C++ Library]を選択する。
- [C++ Library]画面が開くので、以下の項目を設定する。
- プロジェクト名やビルドシステム等を任意のものに設定する。
- [プロジェクトの詳細定義]では、以下の手順で設定する。
- [Type:]は、[Shared Library]
- [Qt module:]は、Qtクラスを使用しない場合は[None]、Qtクラスを使用する場合は[Qt Core]、
- 画面の作成が伴う場合は[Qt Gui]、ウィジェットの作成が伴う場合は[Widget]を選択する。
- [クラス名:]、[ソースファイル名:]、[ヘッダ名:]は任意のものに設定する。
- [Translation File]や[キットの選択]は任意のものに設定する。
プロジェクトをビルドして、静的ライブラリを生成する。
生成されたライブラリは、Windowsの場合は.lib
拡張子、Linuxの場合は.a
拡張子である。
静的ライブラリのリンク
静的ライブラリを他のQtプロジェクトにリンクするには、以下の手順を行う。
- 他のQtプロジェクトにおいて、Qt Creatorのメイン画面にある[プロジェクト]ペインからプロジェクト名を右クリックして、
[ライブラリを追加]を選択する。 - [ライブラリの追加]画面が開くので、以下の項目を設定する。
- [ライブラリの種類]では、[外部ライブラリ]を選択する。
- [外部ライブラリ]では、ライブラリのリンク方法とライブラリのパスを選択する。
[ライブラリファイル:]は、ライブラリが存在するパスを入力する。
[リンク方法]は、[スタティック]を選択する。
- Qtプロジェクトをビルドすることにより、静的ライブラリをリンクすることができる。
動的ライブラリ
動的ライブラリの作成
- QT Creatorのメイン画面から、[ファイル]メニューバー - [ファイル / プロジェクトの新規作成]を選択する。
- [新しいファイルまたはプロジェクト]画面左にある[ライブラリ]から[C++ Library]を選択する。
- [C++ Library]画面が開くので、以下の項目を設定する。
- プロジェクト名やビルドシステム等を任意のものに設定する。
- [プロジェクトの詳細定義]では、以下の手順で設定する。
- [Type:]は、[Shared Library]
- [Qt module:]は、Qtクラスを使用しない場合は[None]、Qtクラスを使用する場合は[Qt Core]、
- 画面の作成が伴う場合は[Qt Gui]、ウィジェットの作成が伴う場合は[Widget]を選択する。
- [クラス名:]、[ソースファイル名:]、[ヘッダ名:]は任意のものに設定する。
- [Translation File]や[キットの選択]は任意のものに設定する。
以下の例では、動的ライブラリとしてダイアログ(QDialogの派生クラス)を作成している。
#ifndef LIBDIALOG_GLOBAL_H
#define LIBDIALOG_GLOBAL_H
#include <QtCore/qglobal.h>
#ifdef Q_OS_WIN // Windows
#if defined(LIBDIALOG_LIBRARY)
#define LIBDIALOG_EXPORT __declspec(dllexport)
#else
#define LIBDIALOG_EXPORT
#endif
#elif Q_OS_LINUX // Linux
#if defined(LIBDIALOG_LIBRARY)
#define LIBDIALOG_EXPORT Q_DECL_EXPORT
#else
#define LIBDIALOG_EXPORT Q_DECL_IMPORT
#endif
#endif
#endif // LIBDIALOG_GLOBAL_H
// LibDialog.h
#ifndef LIBDIALOG_H
#define LIBDIALOG_H
#include "LibDialog_global.h"
#include <QDialog>
class LIBDIALOG_EXPORT LibDialog : public QDialog
{
public:
LibDialog();
};
#endif // LIBDIALOG_H
// LibDialog.cpp
#include "LibDialog.h"
LibDialog::LibDialog()
{
setWindowTitle("Show dialog");
}
動的ライブラリのプロジェクトをビルドして、debugディレクトリまたはreleaseディレクトリにライブラリが生成される。
※注意
Windowsの場合、DLLファイルとaファイルが生成されるため、
aファイルの.a
拡張子を.lib
拡張子に変更する必要がある。
動的ライブラリのリンク
動的ライブラリを他のQtプロジェクトにリンクするには、以下の手順を行う。
- 他のQtプロジェクトにおいて、Qt Creatorのメイン画面にある[プロジェクト]ペインから、
プロジェクト名を右クリックして、[ライブラリを追加]を選択する。 - [ライブラリの追加]画面が開くので、以下の項目を設定する。
- [ライブラリの種類]では、[外部ライブラリ]を選択する。
- [外部ライブラリ]では、ライブラリのリンク方法とライブラリのパスを選択する。
- [ライブラリファイル:]は、動的ライブラリが存在するパスを入力する。(動的ライブラリの
.lib
ファイルまたは.a
ファイルを指定) - [リンク方法]は、[ダイナミック]を選択する。
- [ライブラリファイル:]は、動的ライブラリが存在するパスを入力する。(動的ライブラリの
- これにより、動的ライブラリとして、Qtプロジェクトにリンクすることができる。
Qtプロジェクトのビルドは不要である。
次に、動的ライブラリの機能を使用するため、動的ライブラリのヘッダファイルをインクルードする。
- 動的ライブラリの機能を使用するため、Qt Creatorのメイン画面からにある[プロジェクト]ペインから、
プロジェクト名を右クリックして、[既存のファイルの追加...]を選択する。 - ファイル選択ダイアログから、動的ライブラリのヘッダファイルを追加する。
ヘッダファイルをインクルードすることにより、動的ライブラリの機能が使用できるようになる。 - ただし、動的ライブラリはQT Creatorから独立して実行されるため、実行ファイルと同じディレクトリに動的ライブラリを配置する必要がある。
#include <QCoreApplication>
#include "LibDialog.h"
int main(int argc, char * argv[])
{
QCoreApplication a(argc, argv);
LibDialog dialog;
dialog.show();
return a.exec();
}
動的ライブラリの明示的リンク
Qtには、動的ライブラリの関数を簡単に使用するために、QLibraryクラスが用意されている。
明示的リンクを使用して、動的ライブラリの関数を呼び出す手順は、以下の通りである。
- 動的ライブラリの関数において、C言語のグローバル関数として定義する。
- 動的ライブラリを生成する。
- 動的ライブラリを呼び出す側の実行ファイルと同じディレクトリに、動的ライブラリを配置する。
- QLibraryクラスを使用して、動的ライブラリの関数を呼び出す。
以下の構成を持つ2つのプロジェクトを作成したとする。
- プロジェクト構成
- 動的ライブラリ
- Utils
- 実行ファイル
- Moc
- 動的ライブラリ
まず、Utilsプロジェクトにおいて、関数のみを定義したUtils.cppファイルを作成する。
// Utils_global.h
#ifndef UTILS_GLOBAL_H
#define UTILS_GLOBAL_H
#include <QtCore/qglobal.h>
#ifdef Q_OS_WIN // Windows
#if defined(UTILS_LIBRARY)
#define UTILS_EXPORT __declspec(dllexport)
#else
#define UTILS_EXPORT
#endif
#elif Q_OS_LINUX // Linux
#if defined(UTILS_LIBRARY)
#define UTILS_EXPORT Q_DECL_EXPORT
#else
#define UTILS_EXPORT Q_DECL_IMPORT
#endif
#endif
#endif // LIBDIALOG_GLOBAL_H
// Utils.cpp
#include "Utils_global.h"
#include <iostream>
//#ifdef Q_OS_WIN
// #define UTILS_EXPORT __declspec(dllexport)
//#else
// #define UTILS_EXPORT
//#endif
extern "C" UTILS_EXPORT void SampleHello(int count)
{
while(--count)
{
fprintf(stdout, "Hello!!");
}
}
次に、Mocプロジェクト(動的ライブラリを使用する側)から、動的ライブラリの関数を呼び出す。
QLibraryクラスから呼び出す関数は、必ず、C言語のグローバル関数として定義すること。
これは、マングリングしていない元の名前から関数を呼び出すためである。
※注意
Windowsでは、動的ライブラリから関数を呼び出すには、__declspec(dllexport)
を関数の前に付加すること。
QLibraryクラスのコンストラクタには、.so
拡張子または.dll
拡張子を付加しないライブラリ名を渡す。
動的ライブラリをリンクするには、load
メソッドを実行する。
次に、resolve
メソッドを使用して呼び出す関数名を渡して、関数が存在する場合は関数ポインタが返る。
関数名や型が間違っている場合は、0が返る。
もし、関数内でグローバル変数の値が変更された場合、次の関数を呼び出した時でも、グローバル変数の値を保持し続ける。
// main.cpp
#include <QApplication>
#include <QLibrary>
using SampleFunc = void (*)(int);
int main(int argc, char * argv[])
{
QApplication a(argc, argv);
// 動的ライブラリをリンクする
QLibrary lib("Utils");
lib.load();
// 動的ライブラリの関数を取得する
SampleFunc Func = (SampleFunc)lib.resolve("SampleHello");
if(Func != 0)
{
Func(10);
}
return a.exec();
}