12

そのため、QPlugin システムを使用する QT API に大きく基づいたアプリケーションがあります。使い方はかなり簡単です。インターフェイスから継承するクラスを定義し、プラグインが読み込まれると、そのクラスのインスタンスを取得します。最終的には、OS に適したdlopen/dlsymまたはLoadLibrary/に要約されます。GetProcAddressここで問題はありません。すべてが期待どおりに機能します。

それで、問題に。メイン アプリケーションによって提供されるデータ/関数を参照する必要があるプラグインを含む多くの機能があります。たとえば、私のアプリケーションには GUI があるので、アプリケーションに " plugin::v1::gui" を返す関数がありますQWidget *。プラグインで UI に何かを追加したり、そのダイアログを UI の子にしたりできるようにしたい場合は、それへのポインタが必要です。

私は Linux で開発を始めましたが、すぐに、デフォルトでは、ローダーが共有オブジェクト内の未解決のシンボルを、それをロードするアプリケーションからのシンボルで満たしていないという事実に遭遇しました。問題ありません。簡単に修正できます。-rdynamic" " をフラグに追加して先に進みます。事はうまくいきます。

今、私は Windows に同等のものがないことを発見しました :(。では、良い解決策は何ですか?

これまでのところ、プラグインが気にする可能性のあるすべてのオブジェクト/関数へのポインターを持つメインアプリケーションに入力する構造を持つことが最善です。次に、それをプラグインの " init()" 関数に渡すと、すべてへの適切なポインターが得られますが、何かを追加するたびに複数の場所で変更を加える必要があるため、面倒な解決策です。

より良い解決策はありますか?SO コミュニティはこれにどのように対処しましたか?

4

3 に答える 3

4

アプリケーションによって公開される主要な対話オブジェクトの一連のインターフェイスを作成し、それらを独自の lib/dll に構築し、必要に応じてアプリケーション内のクラスにそれらのインターフェイスを実装します。ライブラリには、プラグイン オブジェクトが実装する「初期化」メソッドだけを含むプラグイン インターフェイスも含まれている必要があります。

アプリケーションとプラグインは明らかにその DLL に対してリンクし、プラグインがアプリケーションによってロードされると、アプリケーションはプラグインの初期化メソッドを呼び出す必要があります。このメソッドには、アプリケーションの制御に必要なオブジェクトを受け入れるためのパラメーターがあります。

これを簡単にする一般的な方法は、プラグインが 1 つのルート オブジェクトからアプリケーション内のすべての関連オブジェクトにアクセスできるように、アプリケーション内に DOM に似た階層を実装することです。

于 2008-12-09T22:42:57.817 に答える
0

公開されたコンポーネントのディクショナリを含む初期化関数でプラグインに渡されるレジストリ オブジェクトを作成します。次に、プラグインがこのレジストリから文字列名またはその他の識別子によってコンポーネントへのポインタを要求できるようにします。安定したインターフェイスのためにコンパイル時の型の安全性を犠牲にします。

CORBAのようなより重いソリューションもあります...

于 2008-12-09T03:40:11.007 に答える
0

あなたはそれを比較的良い方法で行いました。ヘルパー クラスは、多くの場合、新しい機能を挿入する (のみ) ための純粋な方法です。ソフトウェアを新たに設計する場合、すべてのプラグインが管理構造にアクセスできるわけではないことに注意する必要があります。したがって、プラグインの設計に違いがあるはずです。

1 つの可能性: 必要なポインターをウィジェットなどに設定する機能を備えた、継承元の抽象クラスをいくつか作成します。

その他の可能性: getParent().getMainWidget()、getParent().getConfigWidget() ....の関数を使用してメイン(親)クラスを展開します。


ポインターを使用せずに UI プラグインから UI を動的にロードするだけの場合は、次のページで説明されているように実行できます 。 -other-ui_07.html

これは、メインの config-Files などを介してアクセスできる ui-Files で行われます。

于 2008-12-09T13:37:16.607 に答える