web-dev-qa-db-ja.com

CまたはC ++でのプラグインシステムの実装

プラグインスタイルのシステムを実装するためのヒントは何ですか?

30
ixo

Cでは(私自身は行っていませんが、C++もそうだと思います)、これは通常、動的にロードされたモジュールを使用して行われます。そのようなAPIはプラットフォームに依存します。

POSIX(Linux)では、dlopen()ファミリーの関数を使用します。基本的に、プラグインを個別にビルドし、実行時にロードし、名前でシンボルを検索して、それらを呼び出すことができます。

Win32の場合、非常によく似た処理を行うLoadLibrary()があり、コードをDLLにビルドします。

これらすべてを簡単かつ透過的にする便利なラッパーについては、GLibの GModule APIを確認してください。

31
unwind

'92/'93の時間枠で、C++でコーディングされたAldusPageMakerのプラグインアーキテクチャに取り組みました。 PageMakerは、VAMPと呼ばれるC++ OOPフレームワーク上に構築されており、MacOSとWindows間の移植性を支援しました。

そこで、C++の機能を使用してプラグインアーキテクチャを構築しようとしました。これは、いわゆる脆弱な基本クラスの問題のため、C++クラスにとって非常に問題があることが判明しました。ジャーナルに掲載され、OOPSLA'93でリフレクションワークショップで発表した論文を書き始めました。また、ポートランドで開催されたUsenixカンファレンスでBjarne Stroustrupと連絡を取り、数か月間彼と対話を続けました。そこで彼は、私に代わって脆弱な基本クラスの問題に対処する問題を支持しました。 (残念ながら、当時は他の問題がより重要であると考えられていました。)

Microsoftは、COM/DCOMシステムを導入し、そのプラットフォームに対して、問題の実行可能な解決策と見なされていました。 C++は、COMインターフェイスの定義に使用される抽象クラスを介してCOMの実装言語として使用できます。

ただし、最近の開発者はCOM/DCOMを避けています。

対照的に、NeXTは、NeXTステップフレームワークで90年代初頭にObjectiveCを使用してプラグインアーキテクチャを考案しました。今日、それはAppleのコンピューターやiPhoneなどの重要なプラットフォーム上のMac OSXで活気に満ちています。

プラグインの問題を優れた方法で解決できるObjectiveCを提出します。

私は個人的に、C++の脆弱な基本クラスの問題が最も致命的な欠陥であると考えています。

Cベースの言語ファミリーでプラグインアーキテクチャを構築する場合は、ObjectiveCを使用して構築します。

13
RogerV

私が与えることができる最高のプラットフォームと言語中立のアドバイスはこれです:

プラグインSDKを中心にアプリ全体を設計します。

IMO、プラグインSDKは後から考えるべきではありません。基本的にプラグインをロードする空のシェルになるようにアプリを設計すると、コア機能が独自のSDKに実装され、次の利点が得られます。

  • コンポーネントの高いモジュール性、および目的の明確な分離(アーキテクチャを良好にするための一種の強制)
  • それはあなたのSDKを本当に良いものにすることを強制します
  • これにより、他のサードパーティ開発者も非常に強力なコアレベルの機能を作成できます
  • 新しい開発者/採用者は、メインアプリに触れることなく、主要な新機能の作業を簡単に開始できます-プラグインですべての作業を行うことができます(これにより、他のものを台無しにすることを防ぎます)

C/C++では、おそらく動的リンクライブラリと、関数ポインタ(C)またはインターフェイス(C++の場合は純粋仮想メソッドのみで構成されるクラス)のいずれかを使用します。ただし、Javascriptを使用している場合でも、上記のアーキテクチャをお勧めします。

11
AshleysBrain

QtはQPluginLoaderを提供します: http://qt-project.org/doc/qt-4.8/qpluginloader.html

よりきめ細かい制御が必要/必要な場合、QtはQLibraryを使用してライブラリをオンザフライでロードする手段も提供します: http://qt-project.org/doc/qt-4.8/qlibrary.html

さらに良いことに、これらはプラットフォーム間で移植可能です。

5
Andrew Ross

これはあなたが探しているものではないかもしれませんが、Luaなどのスクリプト言語をアプリケーションに埋め込むことができます。 Luaは他のプログラムに埋め込まれるように設計されており、プラグインを作成するためのスクリプト言語として使用されます。 Luaインタープリターをプログラムに追加するのはかなり簡単だと思いますが、Luaを知らないので、これがどれほど効果的なソリューションであるかを保証することはできません。 Luaの使用経験が豊富な他の人は、Luaを別のアプリケーションに埋め込んだ経験についてコメントを追加してください。

もちろん、これはプラグインをLuaで作成する必要があることを意味します。 Luaが気に入らない場合は、de-facto標準のPerl、PythonおよびRubyインタープリターはすべてCで記述されています、 Cプログラムに埋め込むことができます。これらの言語をスクリプト言語拡張として使用するプログラムをいくつか知っています。

しかし、あなたの質問は少し曖昧なので、私はあなたが何を探しているのかわかりません。おそらく、上記のプラグインを使って人々に何をしてもらいたいかについてのより多くの情報が適切でしょう。一部のタスクでは、本格的なスクリプト言語は少しやり過ぎかもしれません。

5
Chris Lutz

プラットフォーム固有のコーディングから(可能な限り)保護するACE( http://www.cs.wustl.edu/~schmidt/ACE.html )のようなフレームワークを使用するのが最善です。

ACEには、動的にアセンブルされたアプリケーションを作成するために使用できる共有ライブラリに基づくプラグインフレームワークが含まれています。

より高いレベルの抽象化については、CIAO( http://www.cs.wustl.edu/~schmidt/CIAO.html )CORBAコンポーネントモデルのオープンソースC++実装を確認してください。

3
lothar

Poco Class Loader を見てください、それはあなたにとって興味深いかもしれません。

2
Torsten

ダイナミックリンクライブラリを使用してプラグインシステムを実装する方法についての記事を書きました。この記事はWindowsプログラマーの観点から書かれていますが、この手法はLinux/Unixタイプの環境にも適用できます。

記事はここで見つけることができます: http://3dgep.com/?p=1759

重要な点は、メインアプリケーション(コアアプリケーション)とプラグイン実装の両方によって暗黙的にリンクされる「共通」DLLを作成する必要があるということです。その後、プラグインを明示的にリンクして、コアアプリケーションによって実行時に動的にロードされます。

この記事では、「共通」DLLを使用して、クラスの静的(シングルトン)インスタンスを複数のDLL間で安全に共有する方法も示しています。

この記事では、「C」関数または変数をDLLからエクスポートし、実行時にアプリケーションでエクスポートされた関数を使用する方法も示しています。

2
Jeremiah
1
none

プラグインライブラリを作成しました Pugg dllファイルからC++クラスをロードします。使用したロジックは次のとおりです。

ユーザーは、一意の名前を持つdllからc関数をエクスポートします。この名前は、dllからのロード中に引数を使用して関数を区別できないため、十分に一意である必要があります。

C関数は、「ドライバ」と呼ばれる1つまたは複数のファクトリクラスを登録します。すべてのDriverクラスは文字列に関連付けられています。メインアプリケーションがクラスを作成する場合、関連する文字列を使用して関連するファクトリクラスを収集します。また、古いプラグインをロードしないようにバージョンチェックシステムを実装しました。

DLLのロードは、LoadLibraryA関数とGetProcAddress関数を使用して実行されます(Puggは現在Windowsで機能します)。

言及する価値のあることの1つは、メインアプリケーションとdllは、同じコンパイラを使用し、同じコンパイルオプション(リリース/デバッグモード、最適化設定、stlバージョンなど)を使用してコンパイルする必要があるということです。そうしないと、クラスのマッピングに問題が発生する可能性があります。

0
tunc

私はかなり素朴なシステムを使用していくつかの成功を収めました:

  • プラグインのAPI仕様を作成する
  • シングルトンプラグインマネージャーを使用する
  • LoadLibrary/GetProcAddressベースのランタイムダイナミックリンクを使用する
  • プラグインに通知するための制御ベースのイベント処理の反転を実装する
0
dirkgently