0

私はQtアプリケーションを構築中です。以前に多くの GUI をプログラミングしたことがありますが、フレームワーク自体に問題はありませんが、プラグインをロードする機能を (C# .NET アプリケーション以外で) プログラミングしたことはありません。私が構築しようとしているプロジェクトには、プラグインが不可欠な部分として含まれています。Qt フレームワークは、ほぼ普遍的にクロスプラットフォームであり、プラグイン用の非常に優れたシステムを備えているように見えるため、これに適していると思いました。

私の問題はこれです: QPluginLoader.instance() メソッドが null 値以外を返すように見えません

私の読書から、これはプラグインが見つからないためです。おそらく何かをするのを忘れていると思いますが、実際にプラグインを作成する方法に関するドキュメントはほとんど見つかりません (例はありますが、信じられないほど詳細ではありません)。プラグインをロードする例はたくさんあり、私はそれを正しく行っていると思いますが、実際にプラグインを作成する例は実際には見つかりませんでした.

これは私がやったことです:

Qt-Creator を使用して、2 つのプロジェクトを作成しました。プラグインを受信するアプリケーションであると見なすウィンドウ アプリケーションと、プラグインであると見なす共有ライブラリ プロジェクトです。

私のウィンドウ化されたアプリケーションには、次のようなヘッダー ファイルがあります。

#ifndef PLUGININTERFACE_H
#define PLUGININTERFACE_H

#include <QtPlugin>

class QStringList;

class PluginInterface
{
public:
    virtual ~PluginInterface() {};

    virtual QStringList messages() const = 0;
};

Q_DECLARE_INTERFACE(PluginInterface,
                    "com.kevincuzner.LearningPlugins.PluginInterface/1.0")

#endif // PLUGININTERFACE_H

私の共有ライブラリ アプリケーションでは、ATestPlugin というクラスを作成しました (これはプロジェクトの TARGET 値でもあります)。

#ifndef ATESTPLUGIN_H
#define ATESTPLUGIN_H

#include "ATestPlugin_global.h"
#include "../LearningPlugins/PluginInterface.h"

#include <QStringList>


class ATESTPLUGINSHARED_EXPORT ATestPlugin : public PluginInterface, public QObject
{

    Q_OBJECT
    Q_INTERFACES(PluginInterface)

public:
    ATestPlugin();

    virtual QStringList messages() const
    {
        //this part is actually defined in the .cpp file, but I don't feel like pasting that here
        QStringList ret;
        ret << "foo" << "bar" << "noms" << "Hello";

        return ret;
    }
};

#endif // ATESTPLUGIN_H

私が配置したATestPlugin.cppファイルの最後にQ_EXPORT_PLUGIN2(ATestPlugin, ATestPlugin)

次に、main メソッドの main.cpp ファイルで次のことを行います (&w はメイン ウィンドウを指します)。

QString text = QFileDialog::getOpenFileName(&w, "Get a file");
QPluginLoader loader(text);
QObject* plugin = loader.instance();
if (plugin)
{
    QMessageBox msgBox;
    msgBox.setText(text);
    msgBox.exec();
}

プログラムを実行し、ポップアップするファイル ダイアログでライブラリ プロジェクトのビルド ディレクトリから libATestPlugin.so を選択すると、*plugin が null であることを意味するメッセージ ボックスが表示されません。以前は、メッセージボックスが常にポップアップして選択したファイル名を表示していたので、その部分が機能していることがわかります。

私のプラグインを QPluginLoader に見えるようにするために何をする必要があるかについて、誰かアイデアはありますか?

4

2 に答える 2

1

それは私にはうまくいきませんでした。以前の TARGET を $$qtLibraryTarget(...) に変更すると、さまざまなプラットフォームでのビルド中に適切な拡張が保証されます。

QPluginLoader でも同じ問題がありました。私がそれをどのように解決したかを簡単に言うと、プラグインライブラリを作成します.lib2.dllの一部を使用するlib1.dllとしましょう。私のアプリケーションでは、QPluginLoader を介して lib1 をロードしようとしています。

QPluginLoader loader( adaptersDir.absoluteFilePath(fileName) );
AdapterInterface* adapterIface = qobject_cast<AdapterInterface*>(loader.instance());

この場合、loader.instance() は 0 を返します。解決策は、lib2.dll をアプリケーション フォルダにコピーすることでした。これは、アプリケーションがプラグイン lib1 を適切にロードするために lib2.dll を使用するためです。

于 2012-10-28T22:48:36.727 に答える
0

さらに実験を重ねた結果、プラグインをロードすることができました。こんなことを言うのは恥ずかしいのですが、これはRTFMの典型的なケースでした。

echo プラグインのチュートリアル(質問を投稿するまで見つけられませんでした) には、プラグインを正しく宣言するために、ライブラリ内の .pro ファイルにいくつかの変更を加える必要がありました。

TARGET = ATestPluginを に変更する必要がありましたTARGET = $$qtLibraryTarget(ATestPlugin)。この変更を行った後、上記のプログラムのメッセージボックスがポップアップし、後で実行して実行qobject_cast< PluginInterface* >(plugin)を依頼PluginInterface->messages()すると、別のクラスに実装されたリストを取得しました。

また、継承順序を変更して QObject を最初に配置しましたが、そのように機能するため、おそらくそのままにしておくでしょう(ただし、違いが生じたかどうかはわかりません)。

于 2012-10-06T22:18:30.330 に答える