10

C++ コードのライブラリを「ホットプラグ」しようとしています。この手法を Linux/Mac/Windows 間のクロス プラットフォームで機能させることに興味があります。基本的に、すべての呼び出し可能なインターフェイスを定義するメイン プログラム #include "StateMachine.h" が必要です。次に、実行時と実行中に StateMachineLibrary.a をロードおよびアンロードして、アプリケーションで異なるステート マシンを使用するようにします。

私が考えているのは、このコンパイルされたコードを自分のmallocされたメモリにロードし、そのメモリに関数ポインタを作成するラッパーを書くようなことでしょうか?

動機は、私のプロジェクトのステート マシンの部分が頻繁に変更され、再コンパイルが必要になることです。また、メイン アプリがさまざまなステート マシンをロードして実行し続けることができるようにします。いくつかの懸念があるため、Luaスクリプトなどの代わりに「ホットプラグ可能な」ライブラリを使用したいと考えているため、代替手段としてすでに検討されていることを考慮してください。

4

7 に答える 7

17

基本インターフェースを定義し、そこから実装を派生させます。これらを動的ライブラリ (DLL/SO) に入れ、実行時にロードします。ライブラリには、その実装のインスタンスを提供するための静的ファクトリ関数が必要です。

// shared
class Base {
 public:
   virtual void DoTheWork() = 0;
};

// within the DLL/SO
class Hotplugged : public Base {
  public:
   virtual void DoTheWork() {
      std::cout<<"I got hotplugged!"<<std::endl;
   }
};

extern "C" Base* CreateIt() {
  return new Hotplugged();
} 

// within the app (sample for Windows/MSVC)
... ::LoadLibrary("mydll");
Base* (*fpCreateIt)() = (Base*(*)())::GetProcAddress(... "CreateIt");
// call the function pointer to obtain a Base instance
Base* mybase = fpCreateIt();

// prints the above text
mybase->DoTheWork(); 
delete mybase;

注:これは単なるスケッチです。これにはいくつかの欠陥があります。たとえば、所有権のセマンティクスを無視しています。また、ロードしたばかりの DLL がバイナリ互換であるかどうかの実際のチェックは行われません。少し考えてみるか、既存の実装を探してください (いくつかは他の回答で言及されています)。

于 2010-06-23T16:47:30.857 に答える
6

これは可能です。クロスプラットフォームの作業 (少なくとも再コンパイルのみ) については、これを行ういくつかの既存のフレームワークを参照することをお勧めします。

OpenSceneGraphには、プラグインをロードおよびアンロードするためのフル機能の「ホットプラグ可能な」実装が含まれています。

Qt にはプラグイン フレームワークもあります。

「トリック」は、プラグイン用のクリーンなインターフェースを持ち、ロードおよびアンロードできる動的ライブラリを使用することです。ほぼすべてのプラットフォーム (すべての主要なプラットフォーム) がライブラリの動的なロードとアンロードをサポートしているため、これが機能するのを妨げるものは何もありません。

于 2010-06-23T16:52:11.380 に答える
2

はい、もちろん可能です。3D グラフィックス API とアプリケーションを開発した以前の役割では、ユーザーがディスプレイ ドライバーを「その場で」選択できるようにしていました。ビューを再作成する必要がありましたが、アプリケーション自体をシャットダウンする必要はありませんでした。

于 2010-06-23T16:48:22.133 に答える
2

その多くの部分はかなり古くなっていますが、Advanced C++ Programming Styles and Idioms (James Coplien) には、そのようなことを行う方法に関するセクションがあり、読み通すのに役立つかもしれません (ただし、単にコピーを購入するかどうかはわかりません)。これ)。

于 2010-06-23T16:51:02.143 に答える
2

Boost.Reflection と Boost.Extension を確認してください。これらは、そのようなことを試みることに伴うさまざまな問題に対処するように設計されています。コンパイラやバージョンを超えて作業することはまだできないと確信していますが、役立つかもしれません.

于 2010-06-23T16:51:26.183 に答える
1

最初に v3c-dcom を書いたのは、それができるかどうかを確認するためだけでした。Sourceforge からダウンロードできます。
現時点では、基本的にプラグイン システムのみです。
他の 3 つの SourceForge プロジェクトに依存しているため、最初にそれらをダウンロードしてインストールする必要があります。

SourceForge http://sourceforge.net/にアクセスして、次のプロジェクトをダウンロードします:
* v3c
* treedb
* meta-treedb
* v3c-dcom

v3cビルド システムと一般的なユーティリティ ライブラリが含まれています。
treedbコアの「永続メモリ」機能が含まれています。
meta-treedbtreedb インライン実装をブランケットでラップし、コンパイル時間とコードの肥大化を短縮します。
v3c-dcomプログラム内でのプラグイン リポジトリの作成、リポジトリへのライブラリの追加、CoCreateInstance()オブジェクトを作成するための呼び出し、それらのオブジェクトのメソッドの呼び出しなど、いくつかの例が含まれています。

ビルドシステムは automake ベースですが、ユーザーフレンドリーになるように設計しました ;)

make && sudo make install各プロジェクトの解凍されたディレクトリで順番に 行うだけです。

あなたが偏執的であるか、「sudo」権限を持っていない場合は、v3c の README と、所有するディレクトリの下でパッケージをアンパック/ビルド/インストールする方法についての「試してみる」スクリプトを読んでください。

make check各ライブラリをそのペースで実行し、v3c-dcom の場合は上記のデモを実行します。

お役に立てれば。

于 2011-02-27T22:16:43.083 に答える
0

そして、XPCOM を忘れないでください。クロスプラットフォームの COM として設計されています。

于 2010-06-23T16:56:46.807 に答える