2016-07-07 5 views
3

プラグインをC++ Linuxプログラムにロードするためのベストプラクティスは何ですか?プラグインを使用したC++プログラムのベストプラクティス

プラグイン(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を使用する=すべてが明らかに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によって簡単に処理できますが、どちらの解決策も汚いと感じます。

プラグインと依存関係の両方を読み込む明確な方法はありますか?どのようにこれをやっている?

答えて

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 
+0

私はRPATHとRUNPATHを避けることを望んでいました。とにかくRPATHは廃止されるはずです。 – JurekM

+0

IIRCの場合、 '$ ORIGIN'はシェルクォートでなければなりません。 –

+0

'libsyntax.so'をリンクするときに、オプション' -Wl、-rpath、/ path1/path2'(libcolor.soが実際にあるパス)を使用します。 –

0

私はLD_LIBARY_PATHがあなたの友人だと思っています。プラグインに必要なライブラリがどこにあるのかをプラグインインターフェイスの定義として定義し、LD_LIBARY_PATHをその場所に設定することをプログラムで確認してください。

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

関連する問題