共有ライブラリの作成
以下のセクションでは、共有ライブラリを作成する際に考慮すべき事項をいくつか挙げます。
共有ライブラリからのシンボルの使用
アプリケーションや他のライブラリなどのクライアントによって使用されることを意図した共有ライブラリに含まれるシンボル(関数、変数、クラス)は、特別な方法でマークする必要があります。これらのシンボルは、エクスポートされるか、または公開される「パブリックシンボル」と呼ばれます。
それ以外のシンボルは、外部から参照できないようにする必要があります。ほとんどのプラットフォームでは、コンパイラがデフォルトでこれらのシンボルを非表示にします。一部のプラットフォームでは、これらのシンボルを非表示にするために特別なコンパイラオプションが必要となります。
共有ライブラリをコンパイルする際は、エクスポート対象としてマークする必要があります。クライアントからその共有ライブラリを使用するには、プラットフォームによっては特別なインポート宣言も必要になる場合があります。
ターゲットプラットフォームに応じて、Qt には必要な定義を含む特別なマクロが用意されています。
- Q_DECL_EXPORT 共有ライブラリをコンパイルする際に使用されるシンボルの宣言には、これを追加する必要があります。
- Q_DECL_IMPORT は、共有ライブラリを使用するクライアントをコンパイルする際に使用されるシンボルの宣言に追加する必要があります。
ここで、共有ライブラリ自体をコンパイルする場合と、単にその共有ライブラリを使用するクライアントをコンパイルする場合とで、適切なマクロが呼び出されるようにする必要があります。通常、これは特別なヘッダーを追加することで解決できます。
mysharedlib という名前の共有ライブラリを作成すると仮定しましょう。このライブラリ用の特別なヘッダーmysharedlib_global.h は、次のような構成になります:
#include <QtCore/QtGlobal>
#if defined(MYSHAREDLIB_LIBRARY)
# define MYSHAREDLIB_EXPORT Q_DECL_EXPORT
#else
# define MYSHAREDLIB_EXPORT Q_DECL_IMPORT
#endifライブラリの各ヘッダーファイルでは、次のように指定します:
#include "mysharedlib_global.h"
MYSHAREDLIB_EXPORT void foo();
class MYSHAREDLIB_EXPORT MyClass...次に、ライブラリ自体をビルドする際に、コンパイラに対して `MYSHAREDLIB_LIBRARY ` が定義されていることを保証する必要があります。これはライブラリのビルドシステムで行います。CMake を使用する場合、共有ライブラリのターゲットを次のように拡張します:
target_compile_definitions(mysharedlib PRIVATE MYSHAREDLIB_LIBRARY)qmake を使用する場合は、
DEFINES += MYSHAREDLIB_LIBRARYを共有ライブラリの.pro ファイルに追加します。
注: Qt Creator および Qt VS Tools のライブラリウィザードでは、これらの設定を自動的に行うためのテンプレートが提供されています。
ヘッダーファイルに関する考慮事項
通常、クライアントは共有ライブラリのパブリックなヘッダーファイルのみをインクルードします。これらのライブラリは、デプロイ時に別の場所にインストールされる場合があります。したがって、共有ライブラリのビルド時に使用されたその他の内部ヘッダーファイルを除外することが重要です。
たとえば、あるライブラリが、ハードウェアデバイスをラップし、サードパーティ製ライブラリによって提供されるそのデバイスへのハンドルを含むクラスを提供している場合を考えます。
#include <footronics/device.h>
class MyDevice {
private:
FOOTRONICS_DEVICE_HANDLE handle;
};集約継承や多重継承を使用する際、Qt Widgets Designer によって作成されるフォームでも同様の状況が発生します:
#include "ui_widget.h"
class MyWidget : public QWidget {
private:
Ui::MyWidget m_ui;
};ライブラリをデプロイする際、内部ヘッダーファイル `footronics/device.h ` や `ui_widget.h` への依存があってはなりません。
これは、さまざまなC++プログラミング書籍で説明されている「実装へのポインタ(Pointer to implementation)」というイディオムを活用することで回避できます。値セマンティクスを持つクラスについては、QSharedDataPointer の使用を検討してください。
バイナリ互換性
共有ライブラリを読み込むクライアントが正しく動作するためには、使用されるクラスのメモリレイアウトが、クライアントのコンパイルに使用されたライブラリバージョンのメモリレイアウトと完全に一致している必要があります。つまり、実行時にクライアントが検出するライブラリは、コンパイル時に使用されたバージョンとバイナリ互換でなければなりません。
クライアントが必要なライブラリをすべて同梱した自己完結型のソフトウェアパッケージである場合、これは通常問題になりません。
しかし、クライアントアプリケーションが、別のインストールパッケージやオペレーティングシステムに属する共有ライブラリに依存している場合は、共有ライブラリのバージョン管理スキームを検討し、どのレベルでバイナリ互換性を維持すべきかを決定する必要があります。例えば、同じメジャーバージョン番号のQt ライブラリは、バイナリ互換性が保証されています。
バイナリ互換性を維持するには、クラスに加えられる変更にいくつかの制限が生じます。詳しい説明は、KDE - Policies/Binary Compatibility Issues With C++ に記載されています。これらの問題は、ライブラリ設計の初期段階から考慮する必要があります。可能な限り、「情報の隠蔽」の原則と「実装へのポインタ」という手法を採用することを推奨します。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.