5

実行可能ファイルを他の共有オブジェクトに「オプションで依存」させたいと考えています。したがって、DSO が存在しない場合は、一部のシンボルなしで実行できます。

呼び出しでこれを実現できdlopen/dlsymますが、各シンボルを手動でロードし、次のようにラッパーを追加する必要があります。

void *my_lib = dlopen("my_lib.so", RTLD_LAZY);  
if (!my_lib)  {
    // ok, I promise not to touch my_lib symbols
} else {
    my_foo_ptr = dlsym(my_lib, "my_foo");
    my_bar_ptr = dlsym(my_lib, "my_bar");
}

... my_foo(...) {
    assert(my_foo_ptr);
    return (*my_foo_ptr)(...);
}

... my_bar(...) {
    assert(my_foo_ptr);
    return (*my_bar_ptr)(...);
}

これはばかげたコードであり、「my_lib.so」ABI に直接依存しているため、ライブラリが更新されるたびに更新する必要があります。

私はこれを行う方法を探してld.soいます。したがって、理想は次のようになります。

void *my_lib = dlopen("my_lib.so", /* bring me all my symbols */);  
if (!my_lib)  {
    // ok, I promise not to touch my_lib symbols
} else {
    // ok, I can directly call symbols from my_lib.so
    my_foo();
    my_bar();
}

しかし、これには 2 つの疑問があり
ます。1. アプリのリンク段階でこれらのシンボルをどうするか? my_lib.so に明示的にリンクすると、アプリはそれに厳密に依存するため、my_lib.so がないと起動できなくなります。そうでない場合は、ld未定義のシンボルについて文句を言います。
2.dlopen()すべての my_lib.so シンボルをアプリで使用できるようにする方法を教えてください。

Upd: マークを付けずに共有ライブラリと明示的にリンクするとうまくいくことに気付きましたDT_NEEDED。しかし、これを行う方法がわかりませldん。

4

3 に答える 3

3

プログラムとこのライブラリ間の相互作用を最小限に抑えるプログラムのニーズを理解するモジュールを作成し、そのコードをライブラリにリンクする方が賢明かもしれません。音楽プレーヤーのようなものを考えてみてください。オーディオ形式ごとにこの種のダンスを行うのではなく、単純なインターフェイスを作成してから、オーディオ形式ごとに個別にコンパイルされたモジュールを作成し、各モジュールを適切なサポートライブラリにリンクさせます。これには、モジュールがすべて同じシンボルを持ち、それらの処理が簡単になるという利点があります。モジュールをロードするときに関数ポインターを使用して構造体を作成し、モジュールを呼び出すときに、構造体がnullであるかどうかを確認します。関数ポインタを呼び出します(これはおそらくマクロを介して行うのが賢明です)。これは、この機能のさまざまなバージョンを簡単に追加できることも意味します。

于 2012-08-15T14:12:46.210 に答える
0

これは可能ですが、おそらく投資するよりも多くの作業が必要になります。それをするために:

  1. GCC のパッチ バージョンを作成する必要があります。特に、「オプションの」シンボル (つまり、シンボルが見つからない場合にダイナミック ローダーが文句を言わないもの) のリストを作成できる binutils を作成する必要があります。

  2. シンボルを理解するには、動的ローダーにパッチを適用する必要があります。

はるかに単純なアプローチは、ツール (= スクリプトまたは単純な C プログラム) が読み取り、定型 C コードを生成するために使用できるDSLを使用することです。

DSL はすべてのシンボル (およびパラメーター) を定義し、ツールは上記のコード テンプレートを使用してそれを .h および .c ファイルに変換します。

変更があった場合my_lib.so(またはさらに多くのシンボルが必要な場合)、(小さな) DSL を編集してスクリプトを再実行するだけです。

于 2012-08-15T12:41:02.640 に答える