質問

C++ のプラグイン システムは、ABI が適切に定義されておらず、各コンパイラ (またはそのバージョン) が独自のルールに従っているため、困難です。ただし、Windows 上の COM は、さまざまなコンパイラを使用するプログラマが単純なインターフェイスを使用してホスト アプリケーション用のプラグインを作成できる最小限のプラグイン システムを作成できることを示しています。

現実的な話をして、この点ではあまり役に立たない C++ 標準については少し脇に置いておきましょう。C++ プラグインをサポートする Windows および Mac (およびオプションで Linux) 用のアプリを作成したい場合、およびプラグイン作成者にかなり幅広いコンパイラの選択肢を提供したい場合 (たとえば、2 年未満のバージョンの Visual C++) 、GCC またはインテルの C++ コンパイラー)、C++ のどの機能を信頼できるでしょうか?

もちろん、プラグインは特定のプラットフォーム用に作成されると想定しています。

思いつく限りの C++ 機能をいくつか挙げ、その答えを以下に示します。

  • vtable レイアウト、抽象クラスを介してオブジェクトを使用するには?(はい)
  • 組み込み型、ポインタ?(はい)
  • 構造体、共用体?(はい)
  • 例外は?(いいえ)
  • 外部「C」関数?(はい)
  • stdcall 組み込みパラメータ型を持つ非外部「C」関数?(はい)
  • ユーザー定義のパラメーター型を持つ非 stdcall 非外部「C」関数?(いいえ)

その分野での経験があれば共有していただければ幸いです。C++ プラグイン システムを備えたある程度の成功を収めているアプリをご存知の場合は、それも役立ちます。

カール

役に立ちましたか?

解決

Dr Dobb's Journal に記事が掲載されました 独自のプラグイン フレームワークを構築する:パート1 このテーマに関してはとても良い読み物です。これは、C/C++ クロスプラットフォーム プラグイン フレームワークのアーキテクチャ、開発、展開をカバーする一連の記事の始まりです。

他のヒント

従来のプラグイン インターフェイスをスクリプト インターフェイスに置き換えることを検討することもできます。C/C++ のいくつかのスクリプト言語には、すでに問題を解決している非常に優れたバインディングがいくつかあります。それらの上に構築するのも悪くないかもしれません。たとえば、次を見てください。 ブースト.Python.

Qt には、私が過去に使用したプラグイン用の非常に優れたシステムがあります。Qt のメタオブジェクト システムを使用して、C++ プラグインを開発しようとするときによく見られる問題の多くを克服します。

一例としては、 Q_DECLARE_INTERFACE 互換性のないプラグインの使用を防ぐために機能します。もう一つは、 ビルドキー, 、アーキテクチャ、OS、コンパイラに適切なプラグインをロードしていることを確認します。Qt のプラグイン システムを使用しない場合は、これらについて心配し、自分で解決策を考案する必要があります。それは必ずしもロケット科学ではありませんし、あなたが失敗するだろうとは言いませんが、Trolltech のスタッフは非常に賢明で、時間をかけてそれについて考えてきました。私は自分で車輪を再発明するよりも、彼らが作成したものを使用したいと考えています。 。

別の例としては、 RTTI 通常、DLL の境界を越えて機能することはありませんが、Qt を使用する場合、次のようなことが起こります。 qobject_cast メタオブジェクト システムに依存するものは、DLL の境界を越えて動作します。

以下に基づいてプラグイン システムを安全に作成できると思います。

  • プラグイン機能のライブラリ (.dll、.so など) へのパッケージ化
  • プラグインが主要な C 言語エクスポートを公開することを要求します。
  • プラグインが抽象 C++ インターフェイスを実装する (そして、そのインターフェイスへのポインタ/参照を返す) ことを要求します。

おそらく最も成功した C++ プラグイン システム:古き良き アドビフォトショップ. 。そうでない場合は、VSTi などの仮想シンセ フォーマットの 1 つ。

不完全な C++ by Matthew Wilson これに関する素晴らしい情報があります。

のアドバイスは次のようです。同じ (または同等の) コンパイラを使用している限り、C++ を使用できます。そうでない場合は、C++ コード上のインターフェイスとして C を使用する方が良いでしょう。

エース クロスプラットフォームのプラグイン アーキテクチャを備えています。

チェックアウト:

  1. エース DLL
  2. ACE DLL マネージャー

本をチェックすることをお勧めします
ACE プログラマーズ ガイド

Firefox は XPCOM 上で動作します (http://www.mozilla.org/projects/xpcom/)。Microsoft COM からインスピレーションを受けていますが、マルチプラットフォームです。

私は C++ プラグイン システムを備えた独自のゲーム エンジンを持っています。

ヘッダー ファイルにいくつかのコードがあるので、プラグインのコンパイル ユニットに入れられます。

メイン エンジンに存在する大きな関数は、エクスポートされた C 関数を介して呼び出されます (プラグインは MyObject_somefunction(MyObject *obj) を呼び出しますが、エンジンでは単に obj->somefunction() を呼び出すだけです)。C 関数の呼び出しが好みに合わない場合は、ヘッダーがプラグインに含まれているときにヘッダーを使用して、C 関数を呼び出すメンバー関数 #define を使用します。

#if defined(IN_THE_PLUGIN)
void MyObject::somefunction() { MyObject_somefunction(this); }
#endif

仮想関数は純粋であるか、コードがヘッダー ファイル内に存在する必要があります。クラスを継承せず、単にクラスをインスタンス化しているだけの場合、仮想関数コードはエンジン内に存在できますが、その場合、クラスは、プラグインから呼び出されるオブジェクトを作成および破棄するためにいくつかの C 関数をエクスポートする必要があります。

基本的に、プラットフォームの完全な独立性を維持することを目的として私が使用したトリックは、C のエクスポートとヘッダー ファイルのトリックにすぎません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top