4

セットアップは次のとおりです。

  1. Aロードするアプリケーションがありますliba.so(コンパイル時にリンクされます)
  2. liba.soシンボルをエクスポートしますexpA
  3. A私はどちらかを制御しませんliba.so
  4. アプリケーション A は、指定したライブラリをlibmine.so同じプロセスにロードできますdlopen(プラグイン アーキテクチャを考えてください)。
  5. expAfromを使用する必要がありますlibmine.soが、明示的にリンクせずにそれを見つける方法がわかりませんliba.so。これは、これまで行ってきたことです。そのシンボルが私のローカルコピーのシンボルと同じアドレスにあることが保証されていないためliba.so(またはそうですか?)、これは現実の世界では機能しないと思います。libmine.soはクローズドソースになり、A.

私はこのようなことをしたことがないので、ライブラリのロードの詳細については少し不明です. たとえば、dlopen("liba.so")内から実行しようとlibmine.soすると、既に読み込まれているライブラリまたは新しいコピーへのハンドルを取得できますか?

ロード方法に関して、libmine.so私が知っているのは、それがロードされることRTLD_LAZYだけです(そして他には何もありません)。

どんな助けや指針も大歓迎です!

4

1 に答える 1

4

すべてのliba.soライブラリがdlopenを使用して編集されている場合、ライブラリを再度開く必要なく、RTLD_GLOBALを使用dlsym(RTLD_DEFAULT, "expA")してシンボルを見つけることができます。

liba.soライブラリがdlopen使用されている場合は、独自の 内で再度RTLD_LOCAL使用してライブラリへのハンドルを取得する必要があります。次の点に注意してください。dlopenlibmine.so

同じライブラリが dlopen() で再度読み込まれると、同じファイル ハンドルが返されます。dl ライブラリはライブラリ ハンドルの参照カウントを維持するため、動的ライブラリは、dlopen() が成功した回数だけ dlclose() が呼び出されるまで解放されません。_init() ルーチンが存在する場合は、一度だけ呼び出されます。ただし、RTLD_NOW を使用した後続の呼び出しでは、RTLD_LAZY で以前にロードされたライブラリのシンボル解決が強制される場合があります。

つまり、ライブラリの同じコピーです。

expA が関数であると仮定すると、メカニズムは (疑似) です: int expA(int value):

int (*fpointer)(int) = NULL;

void *handle = dlopen("liba.so", RTLD_LAZY | RTLD_LOCAL);
if (handle != NULL) {
    void *symbol = dlsym(handle, "expA");
    if (symbol != NULL) {
        fpointer = (int (*)(int ))symbol;
    }
}

これは疑似コードであり、エラー処理はほとんどまたはまったくありません。

于 2013-09-15T11:09:01.283 に答える