QPluginLoaderから読み込みできるプラグインの作り方

大規模なプログラムの場合、機能の全てをプログラムが持っているということはまずなく、プラグインなどによって機能の一部を外部に移していることがほとんどだと思います。

では、どうやってプラグインを作るかというと共有ライブラリを使います。ここでは、QTで共有ライブラリからプラグインを作る方法をまとめてみました。

プラグインクラスの作成

まず、初めにすべてのプラグインが共通に持つ関数を定義したインターフェイスクラスを作ります。

ここでは、例としてGreetPluginInterfaceというインターフェイスを定義します。

#ifndef GREETPLUGININTERFACE_H
#define GREETPLUGININTERFACE_H

#include <QtCore/qplugin.h>

class GreetPluginInterface
{
public:
    virtual ~GreetPluginInterface(){}

    virtual void sayGreet() = 0;
};

Q_DECLARE_INTERFACE(GreetPluginInterface,
                    "com.linden.test.GreetBasePlugin/1.0")

#endif // GREETPLUGININTERFACE_H

プラグイン側で実装する関数(sayGreet関数)を準仮想関数として宣言だけしています。

これだけだとただクラス宣言しただけなのでQ_DECLARE_INTERFACEでインターフェイスだと宣言しています。

そして、このインターフェイスファイルをプラグインを利用する側のプロジェクトに組み込んでください。

プラグインの実装

次に具体的なプラグインを作っていきます。

ここでは、プラグインとしてGreetHeyPluginというプラグインプロジェクトを作ろうと思います。

プロジェクトを作ったらプラグインクラスのヘッダを作ります。

#ifndef GREETHEYPLUGIN_H
#define GREETHEYPLUGIN_H

#include "[インターフェイスのあるディレクトリ]/GreetPluginInterface.h"

#include <QDebug>

class GreetHeyPlugin : public QObject, public GreetPluginInterface
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "com.linden.test.GreetHeyPlugin" FILE "greetheyplugin.json")
    Q_INTERFACES(GreetPluginInterface)

public:
    void sayGreet()
    {
    	qDebug() << "Hey!!";
    }
};
#endif // GREETHEYPLUGIN_H

プラグインにQObjectと先ほど作ったインターフェイスを継承させて、実際に関数を実装すればOKです。

Q_INTERFACESマクロにはインターフェイスの名前を渡してください。

Q_PLUGIN_METADATAについてはプラグインのIDと定義ファイルの名前を渡します。ここでは、greetheyplugin.jsonというファイル名を渡しましたが、まだ作っていないのでプロジェクトで「新しいファイルの追加」からテキストファイルを開き、それをgreetheyplugin.jsonという名前に書き換えます。

内容は次のような空のオブジェクトを書くだけでOKです。

{

}

最後にプロジェクトファイルを開いてプラグインを出力する設定に書き換えます。

TEMPLATE = lib
CONFIG += plugin

これをビルドすればプラグイン用の共有ライブラリが出来上がります。

プラグインの実行

プラグインができたので後はPluginLoaderを使えばファイルからプラグインをロードして実行できます。

QPluginLoader loader("./plugins/pnp_greetheyplugin");
QObject * plugin = loader.instance();
if(plugin != 0){
    GreetPluginInterface * greetPlugin 
        = dynamic_cast<GreetPluginInterface*>(plugin);
    greetPlugin->sayGreet();
}

PluginLoaderのコンストラクタに共有ライブラリのパスを渡し、instanceでインターフェイスをインスタンス化することができます。

あとは実装された関数を自由に呼び出すことが可能です。

まとめ

ここまででプラグインと使用元のプロジェクト構成をまとめると次の画像のようになります。

プロジェクト構成

以上がQTでのプラグインの作り方です。お疲れ様でした!!

関連項目
プライバシーポリシー