2012-02-23 51 views
0

Qt アプリケーションでプラグインで実装できる一連のインターフェイスがあります。すべてのプラグインでは、基本的な説明(説明、 の名前など)を提供するために、少なくとも1つの共通の インターフェイス(Base_plugin)を実装する必要があります。特定のプラグインインターフェイスを呼び出すときは、しばしば にアクセスして、ユーザーインターフェイスに表示する必要があります。これは、次のようなコードの 多くにつながる:複数のインターフェイスを実装し、共通のインターフェイスにキャストするQtPlugins

Foo_plugin* p = getSuitableFooPlugin(); 
// cannot use qobject_cast, plug-in interfaces don't derive QObjects 
Base_plugin* b = dynamic_cast<Foo_plugin*>(p); 
setName(b->name()); 
p->getAction(); 

これはgccの上に少なくとも動作しますが、私は、これはWindows上 仕事に行くされていないことを恐れています。代わりに、reinterpret_castを使用するか、またはそれらをロードするときに正しいプラグインのポインタ を格納することができます( 有効なQObject*があります)。これらの解決策のどちらも実際には私にきれいに見えません。

この問題を回避する方法がありますか?

+0

'Foo_plugin'が' Base_plugin'から継承する場合、この方向に 'dynamic_cast'は必要ありません。実際、基本クラスは 'name()'メソッドを提供しているので、**すべてキャストする必要はありません**。なぜあなたは 'setName(p-> name());'? – ereOn

+0

@ereOnこれは動作するためには仮想継承が必要です( 'Foo_plugin'、' Bar_plugin'などあり、プラグインは一度にすべてを実装できます)。 Qtは仮想ベースとのインタフェースをサポートしていますか? – pmr

+0

Qtやgccに精通していませんが、gccとWindowsの間でこのコードが異なるのはなぜですか(VC++を意味すると思います)。 –

答えて

0

おそらく、私は右のそれを得ていないんだけど、あなただけ書き込むことはできません:Base_pluginからFoo_plugin継承しているので

Foo_plugin* p = getSuitableFooPlugin(); 
setName(p->name()); 
p->getAction(); 

を、そしてBase_plugin::name()が公開されている場合、あなたはキャストせずにそれを呼び出すことができます。

+0

いいえ、 'Base_plugin'と' Foo_plugin'は 'Plugin:pulic QObject、public Foo_plugin、public Base_plugin'のように一つのプラグインで実装された両方のインターフェースです。 – pmr

+0

@ pmr:そうです。おそらく 'Base_plugin'という名前は、すべての' foo_plugin'クラスの* base *クラスであると信じるかもしれないので、ここでは誤解を招くかもしれません。 – ereOn

+0

'Basic'を' Basic'のように考えてください;) – pmr

0

私が理解したよう(あなたは、このようにそれを作るためにリファクタリングについて考えていない場合)、あなたはこのようになめらかを持っているあなたは、プラグインをロードする際

struct IBase 
{ 
    virtual QString name() const = 0; 
    virtual void setName(const QString name&) = 0; 
}; 
Q_DECLARE_INTERFACE(IBase, "best.app.ever.plugins.base"); 

struct IFoo 
{ 
    virtual void foo() = 0; 
}; 
Q_DECALRE_INTERFACE(IFoo, "best.app.ever.plugins.foo"); 

struct Plugin: QObject, IBase, IFoo 
{ 
    Q_OBJECT() 
    Q_INTERFACES(IBase) 
    Q_INTERFACES(IFoo); 

    //.... 
}; 

Q_EXPORT_PLUGIN2(best_app_ever, Plugin); 

は今、あなたがQObject、あなたshoudを取得qobject_castを使用して、このQObjectをインターフェイスクラスにキャストします。

qobject_castの特殊化は、インターフェイスにキャストするプロセスがQ_DECLARE_INTERFACEマクロによって自動的に作成されます。

+0

はい、それは私が持っているものであり、定型的なQtの例です。 _そして、それはあなたが対処していない問題の原因です。 – pmr

+0

@pmr、私のコードはどうやって動かないのですか? – Lol4t0

+0

質問を読む。私はいつもIBaseにキャストしなければならない方法に満足しておらず、それが全く機能しない可能性があります。 – pmr

関連する問題