アプリケーションの規模が大きくなるにつれて、機能をモジュール化し、必要に応じて動的にロード・アンロードできる仕組みが求められることがあります。このようなアーキテクチャでは、アプリケーション本体と独立して開発された「プラグイン」を実行時に読み込むことで、柔軟な拡張性を実現します。
Qtフレームワークでは、QPluginLoaderクラスを用いることで、ダイナミックライブラリ(WindowsではDLL)を簡単にロードできます。以下は、指定したディレクトリからプラグインを検出し、インターフェースを通じて初期化を行うサンプルコードです。
void scanAndLoadPlugins(const QString& pluginDirectory = QString())
{
QString directoryPath = pluginDirectory;
if (directoryPath.isEmpty()) {
directoryPath = QCoreApplication::applicationDirPath() + "/plugins";
}
QDir pluginDir(directoryPath);
if (!pluginDir.exists()) {
qWarning() << "Plugin directory does not exist:" << directoryPath;
return;
}
const auto files = pluginDir.entryInfoList(QStringList("*.dll"), QDir::Files);
for (const auto& fileInfo : files) {
QPluginLoader loader(fileInfo.absoluteFilePath());
if (!loader.load()) {
qWarning() << "Failed to load plugin:" << loader.errorString();
continue;
}
QObject* instance = loader.instance();
if (!instance) {
qWarning() << "Cannot get instance of plugin:" << loader.errorString();
continue;
}
PluginInterface* interface = qobject_cast<PluginInterface*>(instance);
if (interface) {
interface->initialize(PluginContext()); // プラグインの初期化処理
loadedPlugins.append(interface);
} else {
qWarning() << "Plugin does not implement required interface.";
}
}
}
この処理の流れは以下の通りです:
- プラグイン格納ディレクトリを確認
- DLLファイル一覧を取得
- 各ファイルを
QPluginLoaderでロード - インスタンスが取得できれば、対象インターフェースへキャストを試行
- 成功すれば初期化メソッドを呼び出し、管理リストに追加
プラグインとメインアプリケーションとの連携が必要な場合は、初期化時にコンテキスト情報やコールバック関数群を引数として渡す設計とすることが一般的です。