2012-04-28 4 views
2

私は、拡張可能なアーキテクチャのためのC++プラグインフレームワークを設計(ブレーンストーミング)しています。 各プラグインはインターフェイスを登録します。これはプラグイン自体で実装されています。 このようなフレームワークは比較的能力の高い組み込みデバイス(Atom/ARMなど)で動作しているため、STLとBoostを使用できます。C++でのプラグインフレームワーク

現時点では、インターフェイスが事前にわかっていて、プラグイン(ダイナミックライブラリからロードされている)がそれらを実装しているオブジェクトを登録する類似のフレームワークを作成しています。これらのオブジェクトは、必要に応じてファクトリメソッドによってインスタンス化され、メソッドは正しく呼び出されます。

プラグインが新しいインターフェイスを登録して(既存のインターフェイスを実装するだけでなく)、フレームワークユーザーがAPIを利用できるようにして、より柔軟にしたいと考えています。

私はstd :: map < std :: string、FunctionPtr >を使用することを考えました。これは、私が読んだいくつかの記事とstackoverflowの返信でも言及されています。残念ながら、異なるメソッドインターフェースのケースをキャプチャしているようには見えません。

私はテンプレートメタプログラミング、またはおそらく形質と関係があるかもしれないと思っていますが、どのように正確に機能するかはわかりません。誰も助けることができますか?

答えて

2

COMを再実装することによって、これらの問題を解決するXPCOMを見てみてください。

プラグインがアプリケーションに提供するインターフェイスがわからないという問題があります。そのため、開発者がプラグインがアプリケーションにアクセスできるようにする必要があります(ただし、ヘッダーファイルを指定すると、突然あなたはそれが何であるかを知っていて、プラグイン未知のインターフェイスの虚構を必要とせずにコンパイルできます)。インターフェイスを何らかの方法で呼び出すことができるように、フレームワークが任意のメソッドを呼び出すことができるようにするために、私はあなたができる唯一の現実的な方法は、各インターフェイスを個別に読み込まれた関数ポインタのセットとして定義し、コール。そして、それは名前への関数ポインタのマップを意味します。また、関数名を一意にすることで、コンパイラの細かいこと(オーバーロードなど)しかできないことも意味します。コンパイラは、すべての関数を一意のコード化された名前に「マングリング」することによって、これを行います。

Type Traitsは、インポートされた関数をフレームワークにラップするのに役立ちます。したがって、インポートされた関数を検査したり、インポートされた型で動作するクラスを作成したりできます。

おそらく、あなたが読んでみたいアプローチは、VollmannのMetaclasses and Reflectionです。これはC++標準のボディで参照されていましたが、将来の仕様の一部になるかどうかはわかりません。代わりにあなたを見ることができますBoost.Extension

+0

ありがとうございます、私は今のタイプの特性を試してみるつもりです、そして私はBoost.Extensionも見ていきます。 Vollmannの記事は本当に面白いですが、その解決策が「安全」であるかどうかについては非常に心配しています。カプセル化がちょっとねじれているように見えます:) – rippeltippel

0

おそらく最初にチェックする必要があるのはCOMです。

0

テンプレートで行うことができるものは、「テンプレートインスタンス」を手作業で書くことによって、おそらくずっと便利な方法ではありません。

class MyNewShinyInterfaceの宣言が表示されずにフレームワークがコンパイルされた場合、MyNewShinyInterface *のポインタを格納することはできず、フレームワークユーザーに返すことはできません。テンプレートウィザードの量はそれを変更することはできません。フレームワークは、いくつかの基本クラスへのポインタの周りにのみパスを格納することができます。ユーザは、正確にタイプされたポインタを検索するためにdynamic_castを実行する必要があります。

関数ポインタについても同じことが言えます。関数には基本クラスがなく、正しいタイプを取得するにはエラーが発生しやすいreinterpret_castを実行する必要があります。 (これは関数ポインタよりも適切なオブジェクトを好む別の理由です)