2

オープンソース アプリケーション (APP と呼びましょう)、クローズド ソース共有ライブラリ (OPENGL と呼びましょう)、OPENGL 用のオープン ソース プラグイン (PLUGIN と呼びましょう) [共有ライブラリとも呼びます] の 3 つがあります。
OS: リナックス。

APPとPLUGINの間でデータを共有する必要があるため、APPはPLUGINとリンクし、実行するとシステムが自動的にロードします。

その後、APP は OPENGL に属する eglInitialize を呼び出し、その後、この関数は PLUGIN を再度ロードします。

その後、APPメモリにPLUGINの2つのコピーがあります。

PLUGIN のおかげでグローバル データがあることはわかっています。デバッグ後、グローバル データのコピーが 2 つあることがわかりました。

では、この動作を修正するにはどうすればよいでしょうか? APP と OPENGL で使用される PLUGIN の 1 つのインスタンスが必要です。また、OPENGL ライブラリを変更できません。

4

2 に答える 2

2

それは明らかに、ライブラリが何をしているかに大きく依存しますが、一般的には何らかの解決策が可能なはずです。

最初に、通常、同じ名前の共有ライブラリが複数回ロードされた場合、同じライブラリを引き続き使用することに注意してください。これは主に、標準のローディング/リンク メカニズムを介したローディングに適用されます。dlopenライブラリが独自に呼び出す場合でも、同じライブラリを取得できますが、フラグに依存しdlopenます。dlopen のドキュメントを読んで、dlopen がどのように機能し、どのように操作できるかを理解してください。

PLUGIN をリンカ コマンドの早い段階で配置して、最初に読み込まれるようにして、後の二重読み込みを回避することもできます。PLUGIN を動的にロードする必要がある場合、これは明らかに役に立ちません。LD_PRELOADリンク順序を解決できるかどうかを確認することもできます。

最後の手段としてLD_LIBARY_PATH、実際のライブラリからインターフェイス ライブラリを使用して配置する必要がある場合があります。これは単純に呼び出しを実際の呼び出しに渡しますが、重複したロードをインターセプトし、それらを前のロードにシャントします。

これは、考慮すべき一般的な方向性です。実際の答えは、コードと他の共有ライブラリの機能に大きく依存します。他のオプションに入る前に、リンカのロード順序を最初に調べてください。

于 2012-09-13T18:39:56.123 に答える
1

OPENGL がRTLD_LOCALフラグ付きの PLUGIN をロードしていると思われます。これは通常、複数のプラグインが競合しないように、プラグインをロードするときに必要なものです。

Java でコードをロードする際にも同様の問題がありました。十数個の異なるモジュールをロードすると、それらは互いに通信できなくなりました。私たちのソリューションがうまくいく可能性があります。私たちはプラグインのラッパーを作成し、ラッパーがプラグインであることを Java に伝えました。そのプラグインは、 with を使用dlopen して、他の共有オブジェクトをそれぞれロードしましたRTLD_GLOBAL。これはプラグイン間で機能しました。ただし、プラグインがメインに戻ることができるかどうかはわかりません(ただし、そうすべきだと思います)。また、IIRC では、main をリンクしてそのシンボルを使用できるようにするときに、特別なオプションが必要になります。Linux は main のシンボルを、main が別の方法でロードされたかのように扱うと思いRTLD_LOCALます。(たぶん --export-dynamic?これをしなければならなかったのは久しぶりで、正確には思い出せません。)

于 2012-09-13T19:35:04.177 に答える