リンカーとライブラリ

追加オブジェクトの読み込み

追加オブジェクトは、dlopen(3DL) を使用して、実行プロセスのアドレススペースに追加できます。この関数は、引数としてファイル名と結合モードを入手し、アプリケーションにハンドルを戻します。このハンドルを使用すると、アプリケーションは、dlsym(3DL) を使用することによってシンボルを配置できます。

パス名が、単純ファイル名で指定されている (名前の中に「/」が組み込まれていない) 場合、実行時リンカーは一連の規則を使用して、適切なパス名を生成します。「/」が組み込まれたパス名は、そのまま使用されます。

これらの検索パスの規則は、最初の依存関係の配置に使用された規則と全く同じものです。実行時リンカーが検索するディレクトリを参照してください。 たとえば、ファイル main.c は、以下のようなコードフラグメントが組み込まれているとします。


#include        <stdio.h>
#include        <dlfcn.h>
 
main(int argc, char ** argv)
{
        void *  handle;
        .....
 
        if ((handle = dlopen("foo.so.1", RTLD_LAZY)) == NULL) {
                (void) printf("dlopen: %s\n", dlerror());
                exit (1);
        }
        .....

共有オブジェクト foo.so.1 を配置するために、実行時リンカーは、プロセスの初期設定時に表示された LD_LIBRARY_PATH 定義に、リンク編集 prog 中に指定された実行パスを続けます。デフォルトの位置として、/usr/lib ( 32 ビットオブジェクトの場合) と /usr/lib/64 (64 ビットオブジェクトの場合) を使用します。

パス名が次のように指定されているとします。


        if ((handle = dlopen("./foo.so.1", RTLD_LAZY)) == NULL) {

実行時リンカーは、プロセスの現在の作業ディレクトリ内でこのファイルだけを検索します。


注 –

lopen(3DL) を使用して指定された共有オブジェクトは、そのバージョンのファイル名で参照することをお勧めします。バージョンについての詳細は、バージョン管理ファイル名の管理 を参照してください。


必要なオブジェクトが配置されていない場合は、dlopen(3DL) によって NULL ハンドルが戻されます。この場合、dlerror(3DL) を使用すると、失敗した真の理由を表示できます。次に例を示します。


$ cc -o prog main.c -ldl
$ prog
dlopen: ld.so.1: prog: fatal: foo.so.1: open failed: No such \
file or directory

dlopen(3DL) によって追加されたオブジェクトに、他のオブジェクトに依存する関係がある場合、その依存関係もプロセスのアドレススペースに配置されます。このプロセスは、指定されたオブジェクトの依存関係がすべて読み込まれるまで継続されます。この依存関係のツリーを「グループ」と呼びます。

dlopen(3DL) によって指定されたオブジェクト、または依存関係がすでにプロセスイメージの一部である場合は、そのオブジェクトはこれ以上処理されません。この場合でも有効なハンドルは、アプリケーションに戻されます。このメカニズムにより、同じオブジェクトが複数回読み込まれることを防ぐことができます。また、このメカニズムを使用すると、アプリケーションは専用のハンドルを入手できます。たとえば、前述した main.c の例には、次のような dlopen() 呼び出しが組み込まれているとします。


        if ((handle = dlopen((const char *)0, RTLD_LAZY)) == NULL) {

この場合、dlopen(3DL) から戻されたハンドルは、アプリケーションそのものの中、プロセスの初期設定の一部として読み込まれた依存関係の中、または RTLD_GLOBAL フラグが指定された dlopen(3DL) を使用してプロセスのアドレススペースに追加されたオブジェクトの中のシンボルを配置できます。