リンカーとライブラリ

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

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

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

これらの検索パスの規則は、最初の依存関係の配置に使用された規則と全く同じものです (「実行時リンカーによって検索されるディレクトリ」を参照)。たとえば、ファイル main.c は、以下のようなコードフラグメントが組み込まれている場合、共有オブジェクト foo.so.1 を配置するために、実行時リンカーは、プロセスの初期設定時に表示された LD_LIBRARY_PATH 定義に、リンク編集 prog 中に指定された実行パスを続けて入力し、最後にデフォルトのロケーション /usr/lib を入力して使用します。


#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);
    }
    .....

ファイル名が次のように指定されている場合、実行時リンカーは、プロセスの現在の作業ディレクトリ内でこのファイルだけを検索します。


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

注 -

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


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