総合手引 | セクション 3 | English | オプション |
#include <dlfcn.h>
dlopen() は、 path 内の共有オブジェクトへのアクセスを提供し、 dlsym() と dlclose() の呼び出しにおいて、オブジェクトを後で参照するために使用可能な 記述子を返します。 dlopen() を呼び出す前に path がアドレス空間内になかった場合はアドレス空間に配置されます。 この方法で、オブジェクトが 初めてアドレス空間にロードされるとき、関数 _init() が存在すればそれが動的リンカによって呼び出されます。 先の dlopen() 呼び出しでアドレス空間内に path が既に配置されている場合、2 度目は追加されません。 しかし、 path 上での dlopen() 操作の参照カウント値は管理されます。 path に指定されたものが NULL ポインタであれば、プロセスの メイン実行可能モジュールへの参照として解釈されます。 mode は、ロードされたオブジェクトからの外部関数への参照が、 どのようにその参照先と結合するか、その方法を制御します。 これには次の値のうちの 1 つが含まれていなくてはなりません。 おそらくは、後で述べる追加フラグとの OR をとった値に なるでしょう。
RTLD_LAZY | 外部関数への参照はそれぞれ関数が最初に呼び出されるときに解決されます。 |
RTLD_NOW | 外部関数への参照はすべて dlopen() によってただちに結合されます。 |
RTLD_LAZY は、効率を良くするという理由で一般的に好ましいです。しかし、 dlopen() を呼び出している間に未定義シンボルを確実に発見するためには RTLD_NOW が便利です。
次のフラグの 1 つを OR をとって mode 引数の中に含めることができます。
RTLD_GLOBAL | この共有オブジェクトから得られるシンボルおよび 必要とされるオブジェクトの有向非巡回グラフ (DAG) が、 その他すべての共有オブジェクトからの未解決の参照を 解決するために利用可能になります。 |
RTLD_LOCAL | この共有オブジェクトから得られるシンボルおよび 必要とされるオブジェクトの有向非巡回グラフ (DAG) が、 同一の共有オブジェクトからの未解決の参照を 解決するために利用可能になります。 こちらがデフォルトの動作ですが、このフラグを用いて 明示的に指定することができます。 |
dlopen() は、処理が失敗すると NULL ポインタを返し、 dlerror() で問い合わせできるエラー状態を設定します。
dlsym() は、 symbol が handle で識別される共有オブジェクト内で 発生したときと同様に、ヌル文字で終了する文字列 symbol で記述されたシンボルのアドレス結合を返します。 dlopen() によってアドレス空間に追加されたオブジェクトによってエクスポートされる シンボルは、 dlsym() 呼び出しを通してのみアクセス可能です。 このようなシンボルは、オブジェクトがロードされる際に、すでに アドレス空間に存在しているシンボルの定義に置き換わるものでは ありませんし、通常の動的リンク参照を満たすために利用可能な ものでもありません。
dlsym() が特別な handle NULL を使用して呼び出された場合は、 そのハンドルは呼び出しがされている実行ファイルあるいは 共有オブジェクトへの参照として解釈されます。このため、 共有オブジェクトは自分自身の持つシンボルを 参照できるのです。
dlsym() が特別な handle RTLD_DEFAULT を使用して呼び出された場合は、オブジェクトが ロードされる際に未定義のシンボルを解決するために 使用されるアルゴリズムに従ってシンボルを探索します。 探索されるオブジェクトは次のように書かれた順番になります。
dlsym() が特別な handle RTLD_NEXT を使用して呼び出された場合、シンボルの検索は、 dlsym() 呼び出しを発行した後でロードされた共有オブジェクトに制限されます。 そのため、メインプログラムからこの関数が呼び出された場合、 すべての共有ライブラリが検索されます。この関数が共有ライブラリから 呼び出された場合、 その共有ライブラリより後でロードされる共有ライブラリすべてが 検索されます。 RTLD_NEXT はライブラリ関数を包み込むラッパを実装するのに便利です。 例えば、ラッパ関数 getpid() がある場合、関数内で dlsym(RTLD_NEXT, amp;"getpidamp;") を使用すれば "本物の" getpid() にアクセスできるでしょう。
シンボルが見つけられなかった場合、 dlsym() は null ポインタを返し、エラー状態を設定します。 エラー状態は dlerror() を使用して問い合わせることができます。
dlerror() は、 dlopen(), dlsym(), または dlclose() 呼び出しの間に発生した最後のエラーを記述する ヌル文字で終了する文字列を返します。 このようなエラーが発生していない場合、 dlerror() は NULL ポインタを返します。 dlerror() を呼び出すたびに、エラー指示がリセットされます。 そのため、後の呼び出しが先の呼び出しの直後にくるような dlerror() 呼び出しを行った場合、後の呼び出しでは必ず NULL ポインタが 返ってきます。
dlclose() は handle が参照する共有オブジェクトへの参照を削除します。 参照カウント値が減らされ 0 になると、そのオブジェクトはアドレス空間から 削除され handle は無効になります。この方法で共有オブジェクトを除去する直前に、 _fini() 関数がこのオブジェクトで定義されている場合には それを呼び出します。 dlclose() は、処理が成功すると値 0 を返します。 そうでない場合は -1 を返し、 エラー状態を設定します。エラー状態は dlerror() で問い合わせできます。
オブジェクトに固有の関数 _init() と _fini() は、引数なしに呼び出され、戻り値は期待されていません。
以前の実装では、C 言語からコンパイルしたオブジェクトコードと
シンボルの互換性を持たせることができるように、
外部シンボルにはすべてアンダスコアを先頭につける必要が
ありました。現在でも、
C 言語のコンパイラに対して (非推奨ですが)
DLOPEN (3) | September 24, 1989 |
総合手引 | セクション 3 | English | オプション |
このマニュアルページサービスについてのご意見は Ben Bullock にお知らせください。 Privacy policy.
“ | The number of UNIX installations has grown to 10, with more expected. | ” |
— UNIX Programming Manual, 1972 |