2

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

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

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

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

テンプレートのメタプログラミングや特性に関係があるのではないかと思いますが、正確にどのように機能するのかわかりません。誰でも助けることができますか?

4

3 に答える 3

2

これらの問題を解決する XPCOM を調べてみてください - COM の再実装のようなものです。

プラグインがアプリケーションに提供するインターフェイスがわからないという問題があるため、コンパイラがそれが何であるかを知らなくても、開発者がそれにアクセスする方法が必要です (ただし、ヘッダー ファイルを指定すると、突然わかります)それが何であり、プラグインの不明なインターフェースの空想を必要とせずにコンパイルできます)

そのため、インターフェイスのランタイム決定論に依存する必要があります。これには、フレームワークが任意のメソッドを呼び出すことができるように、何らかの方法でインターフェイスを定義することが大まかに必要です。それを行うことができる唯一の現実的な方法だと思います個別にロードされ、ユーザーが呼び出すためにデータに格納される一連の関数ポインターとして各インターフェイスを定義することです。そして、それは名前への関数ポインタのマップを意味します。また、関数名を一意にすることによって、コンパイラの機能 (オーバーロードなど) のみを使用できることも意味します。コンパイラは、すべての関数を一意のコード化された名前に「マングリング」することにより、これを行います。

の特徴は、インポートした関数をフレームワークにラップするのに役立ちます。そのため、それらを調べて、インポートされた任意の型で動作するクラスを作成できますが、任意の関数をインポートするという主な問題は解決しません。

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

于 2012-04-28T14:48:00.733 に答える
0

おそらく、最初に確認する必要があるのは COM です。

于 2012-04-28T09:32:59.083 に答える
0

テンプレートを使用して実行できることはすべて、"テンプレート インスタンス" を手動で作成することにより、おそらくはるかに不便な方法で実行できます。

フレームワークが の宣言を確認せずにコンパイルされた場合、class MyNewShinyInterfaceタイプ のポインターを格納できずMyNewShinyInterface *、それらをフレームワーク ユーザーに返すことができません。テンプレートの魔法でそれを変えることはできません。フレームワークは、一部の基本クラスへのポインターのパス アラウンドのみを格納できます。ユーザーはdynamic_cast、正しく入力されたポインターを取得するために、 a を実行する必要があります。

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

于 2012-04-28T09:33:59.760 に答える