3

プラグインを C++ Linux プログラムにロードするためのベスト プラクティスは何かについて、誰かが光を当てることができますか?

プラグイン (libsyntax.so) を備えたプログラム (エディター) があるとします。エディターの構成ファイルには、libsyntax.so ライブラリー (plugin1=/opt/editor/gizmos/libsyntax.so) へのパスが含まれています。エディターは構成を読み取り、次を呼び出します。

void* library = dlopen(path, RTLD_NOW|RTLD_GLOBAL);
MYFUN* function = (MYFUN*)dlsym(library, "function");

すべて問題ありません。

(libsyntax.so) がヘルパー ライブラリ (libcolor.so) に依存しているとします。readelf を実行すると、次のようになります。

readelf -d libsyntax.so 

Dynamic section at offset 0x12b6b48 contains 31 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libcolor.so]
 ...

ただし、この時点で上記の dlopen() は失敗し、エラーは「そのようなファイルまたはディレクトリはありません」です。LD_DEBUG=all を使用すると、libsyntax.so がロードされた後、メッセージが次のようになることがわかります。

28664:  file=libcolor.so [0];  needed by /home/.../libsyntax.so [0]
28664:  find library=libcolor.so [0]; searching
28664:   search cache=/etc/ld.so.cache
28664:   search path=/lib64/tls/x86_64:/lib64/tls:...:/usr/lib64 (system search path)
28664:    trying file=/lib64/tls/x86_64/libcolor.so
          ... and so on

ローダー/リンカーは標準的な場所を探していますが、明らかに、依存関係が見つかりません。これは ldconfig または LD_LIBRARY_PATH で簡単に処理できますが、どちらのソリューションも汚いと感じます。

プラグインと依存関係の両方をロードするクリーンな方法はありますか? どうやってこれをやっていますか?

4

2 に答える 2

1

依存関係を確実に見つけるためのクリーンな方法は、プログラムとそのプラグインをリンクする際に、実行時検索パス ( RPATH ) を、依存関係が見つかる適切な場所に設定することです。

rpath がバイナリに設定されている場合 (これは で確認できますreadelf)、リンカーは、デフォルトのシステムの場所に加えて、そこにリストされている追加のパスを使用しますLD_LIBRARY_PATH

$ORIGINさらに、実行時に常に現在のバイナリの場所に解決される特別な変数があり、それに対する相対パスを設定できます!

たとえば、アプリケーションのルート パス (メインの実行可能ファイルを含む) が/opt/editorで、プラグインが の下/opt/editor/gizmosにあり、追加の依存関係を持つ別のフォルダーがある/opt/editor/libとします。リンカー オプションを使用できます。

# editor executable
-Wl,-rpath=$ORIGIN/lib
# plugins
-Wl,-rpath=$ORIGIN/../lib,-rpath=$ORIGIN
于 2016-07-07T21:20:58.047 に答える
0

個人的には、ここでは LD_LIBARY_PATH があなたの味方だと思います。プラグイン インターフェイスの定義として、プラグインが必要とするライブラリを配置する場所を定義し、プログラムで LD_LIBARY_PATH をその場所に設定するようにします。

ライブラリをロードするには、dlopen を呼び出す前に設定するだけで十分です。プログラムに他の変更は必要なく、プラグイン自体の特別なリンクも必要ありません。

于 2016-07-09T13:57:19.940 に答える