3

プラグインで拡張したい Qt でアプリケーションを作成しています。私のアプリケーションには、プラグインが使用するライブラリもあります。だから、私は双方向のコミュニケーションが必要です。基本的に、プラグインはライブラリを呼び出すことができ、プラグインをロードする私のアプリケーションはそれらを呼び出します。

現在、私のライブラリは C++ で書かれているので、いくつかのクラスがあります。プラグインはヘッダー ファイルをインクルードし、それにリンクして使用できます。また、プラグインが実装する必要がある抽象基本クラスである、インターフェイスを含むヘッダー ファイルもあります。また、そのクラスへのポインターを返す関数をエクスポートし、C リンケージを使用する必要があります。

ここまでは、すべてが明確で、標準のプラグイン インターフェイスであると思います。ただし、3 つの主な問題、またはサブタスクがあります。

  1. 他の言語からライブラリを使用するには? Pythonのみでこれを試しました。SIP を使用して Python コンポーネントを生成し、それを test.py ファイルに正常にインポートして、ライブラリ内のクラスから関数を呼び出しました。他の言語で試したことはありません。

  2. 他の言語で抽象クラスの適切な宣言またはスタブを生成するにはどうすればよいですか? プラグインはこのクラスを実装する必要があるため、Python の .py ファイル、Java の .class ファイルなど、他の言語のヘッダーに相当するものを何とか生成できるはずです。これはまだ試していませんが、他の言語用のジェネレータがあるとします。

  3. プラグインでオブジェクトのインスタンスを作成するにはどうすればよいですか? ここまで来れば、クラスはプラグインに実装されます。ここで、実装された抽象クラスのインスタンスを返す関数を呼び出し、それへのポインターを取得する必要があります。私の調査によると、これを機能させるには、Python インタープリター、JVM などのハンドルを取得し、そこからプラグインと通信する必要があります。

それほど複雑には見えませんが、調査を開始したときは、最も単純なケースでもかなりの作業が必要でした。そして、私は最初のポイントにのみ、Pythonでのみ成功しました。それは私が正しいアプローチを取っているかどうか疑問に思いましたか?これについてどう思いますか..ライブラリと抽象基本クラスでQtを使用するべきではなかったかもしれませんが、純粋なC ++のみを使用する必要がありました。おそらく、物事が少し簡単になる可能性があります。または、ライブラリで C のみを使用し、プラグインがクラスではなく C 構造体を返すようにするべきだったのかもしれません。ライブラリを呼び出すのは些細なことなので、物事がずっと簡単になると私は信じています。そして、C 構造体の実装は、C++ クラスを実装するよりもはるかに簡単であり、Qt オブジェクトを使用する C++ クラスを実装するよりもさらに簡単だと思います。

私を正しい方向に向けて、これに関するあなたの専門知識を共有してください。また、このテーマに関する本をご存知でしたら、喜んで購入させていただきます。または、これに対処するいくつかのリンクが必要です。

4

1 に答える 1

1

C++ はそのシンボルを破壊し、クラスを定義するための特別な魔法を持っています。これは、標準 (C) オブジェクト ファイルの上に一種のハッキングされたものです。他の言語のファイルにその魔法を理解させたくありません。だから私は確かに純粋なCですべてを行うというあなた自身の提案に従います.

ただし、それは C++ を使用できないという意味ではありません。実装ではなく、インターフェイスのみが C である必要があります。もっと厳密に言えば、生成されるオブジェクト ファイルは、他の言語が使用しない特別な機能を使用してはなりません。

プラグインがプログラムにリンクしてそこから関数を使用することは可能ですが、個人的には、ロード後にプラグイン関数を呼び出して、プラグイン。

  1. すべての言語は、共有オブジェクト (SO または DLL) ファイルを開くことをサポートしています。それを使用します。

  2. インターフェイスは、いくつかの引数と戻り値の型を持つ関数で構成されます。おそらく、それらの受け渡しや取得の方法に特別なニーズがあります。おそらく自動化されたシステムがあると思いますが、個人的にはインターフェースファイルを手で書くだけです。最も重要なことは、インターフェースを適切に文書化することです。これにより、ユーザーは自分の言語からオブジェクト ファイルをロードする方法を知っている限り、任意の言語を使用できるようになります。

  3. 言語が異なれば、オブジェクトを格納する方法も大きく異なります。データの作成者をメモリの所有者にすることをお勧めします。したがって、プログラムにコンストラクターを持つクラス (プラグイン インターフェイスの C 関数でラップされている) がある場合、そのクラスがデータを作成するクラスであり、プラグインではなくプログラムがそれを所有する必要があります。これは、プラグインが処理が完了したときにプログラムに通知する必要があり、その時点でプログラムがプラグインを破棄できることを意味します (もちろん、まだ必要でない限り)。Python や C++ など、それをサポートする言語では、インターフェイス オブジェクトが破棄されたときに、これを自動的に行うことができます。(ここでは、プラグインが実際のオブジェクトと通信する目的でオブジェクトを作成すると想定しています。このオブジェクトは実際のオブジェクトのように動作しますが、C ではなくターゲット言語で動作します。)

ライブラリ (Qt など) をインターフェイスから除外します。「リソース #x を画面上のこの位置に配置する」などの機能は許可できますが、「この Qt オブジェクトを画面上のこの位置に配置する」ことはできません。その理由は、プラグインに Qt オブジェクトを渡すように要求する場合、Qt を理解する必要があり、プラグインの作成が非常に難しくなるためです。

プラグインが完全に信頼されている場合は、それらのオブジェクトへの (不透明な) ポインターを渡すことを許可できますが、他の数値型を使用する場合と変わらないインターフェイスに対してです。プログラムで関数を呼び出す以外に、オブジェクトを操作する必要はありません。

于 2012-11-26T10:45:45.540 に答える