|
HOME > Linux Tips ( 目次 ) > Linux コマンド 一覧表 > d > dlopen - ライブラリコールの説明 dlopen - ライブラリコールの説明 - Linux コマンド集 一覧表名前dlclose, dlerror, dlopen, dlsym - 動的リンクを行うローダへの プログラミングインターフェース 書式
#include <dlfcn.h>
説明dlopen (), dlsym (), dlclose (), dlerror ()の 4つの関数は、動的リンク (dynamic linking) を行うローダへの インタフェースを実装したものである。 dlerror関数 dlerror ()は、前回 dlerror ()が呼び出された後に、 dlopen (), dlsym (), dlclose ()のいずれかで最後に発生したエラーについての説明メッセージを返す。 初期化後または前回呼び出された後で、エラーが発生していなければ NULL を返す。 dlopen
関数
dlopen
()は、NULL 終端された文字列
filename
で指定されたファイル名の動的ライブラリ (dynamic library) をロードし、
その動的ライブラリへの内部「ハンドル」を返す。
filename
が NULL の場合、メイン・プログラムへのハンドルが返される。
filename
がスラッシュ ("/") を含む場合、(相対か絶対かの)パス名として解釈される。
それ以外の場合、動的リンカは以下の手順でライブラリを検索する
(詳細は
ld.so
(8) を参照):
そのライブラリが他の共有ライブラリに依存している場合は、 依存しているライブラリも動的リンカが同じ検索ルールに基づいて 自動的にロードする (それらのライブラリにさらに依存関係がある場合などは この処理は再帰的に行われる)。 flag には以下の 2 つの値のいずれかを含めなければならない:
dlsym関数 dlsym ()は、 dlopen ()が返した動的ライブラリの「ハンドル」と、 NULL 終端されたシンボル名の文字列を引き数に取り、 そのシンボルがロードされたメモリのアドレスを返す。 シンボルが、指定されたライブラリと、指定されたライブラリがロードされる際に dlopen ()が自動的にロードしてライブラリのいずれにも見つからない場合には、 dlsym ()は NULL を返す ( dlsym ()による検索は、これらのライブラリの依存関係のツリーを先頭から 辿って行われる)。 実際にはシンボルの値自体が NULL になることもある (そのため、 dlsym ()の返り値が NULL であったとしても必ずしもエラーという訳ではない)。 エラーかどうかを確認する正しい方法は以下の通りである: dlerror ()を呼び出して以前のエラー状態をクリアしてから、 dlsym ()を呼び出す。その後でもう一度 dlerror ()を呼び出して、 dlerror ()の返り値を変数に保存し、保存した値が NULL であるか判定する。 RTLD_DEFAULT と RTLD_NEXT という二つの特別な擬似ハンドルがある。 RTLD_DEFAULT は、デフォルトのライブラリ検索順序にしたがって、 検索対象のシンボルが最初に現れるところを探す。 RTLD_NEXT は、ライブラリ検索順序の中で現在のライブラリ以降で最初に 関数が現れるところを探す。この機能を使うことで、別の共有ライブラリの 関数へのラッパーを提供することができる。 dlclose関数 dlclose ()は動的ライブラリのハンドル handle の参照カウントを 1 減らす。参照カウントが 0 になり、ロードされている 他のライブラリからそのライブラリ内のシンボルが使われていなければ、 その動的ライブラリをアンロードする。 関数 dlclose ()は、成功した場合は 0 を返し、エラーの場合 0 以外を返す。 廃止されたシンボル _init と _finiリンカは _init と _fini を特別なシンボルと解釈する。 ある動的ライブラリで _init という名前のルーチンがエクスポートされていれば、 そのコードは、ライブラリのロード後、かつ dlopen ()が復帰する前に実行される。 その動的ライブラリで _fini という名前のルーチンがエクスポートされていれば、 ライブラリがアンロードされる直前にそのルーチンが呼び出される。 システムの起動ファイルに対するリンクを避ける必要がある場合、 gcc のコマンドラインに "-nostartfiles" オプションを指定すればよい。 このルーチンや、gcc のオプション -nostartfiles や -nostdlib は使用しないことを推奨する。 これらを使うと、望ましくない動作をすることがある。 なぜなら、(特別な措置が行われない限り) これらの constructor/destructor ルーチンは実行されないからである。 代わりに、ライブラリは __attribute__((constructor)) や __attribute__((destructor)) の関数属性を使って必要なルーチンをエクスポートするのがよい。 これらについては gcc の info ページを参照のこと。 constructor ルーチンは dlopen ()が復帰する前に実行され、 destructor ルーチンは dlclose ()が復帰する前に実行される。 GNU での拡張
glibc では POSIX には記載されていない関数が 2つ追加されている。
プロトタイプは以下の通りである。
#define _GNU_SOURCE#include <dlfcn.h> 関数
dladdr
()は、関数のポインタを引き数にとり、関数の名前と関数が定義されている
ファイルの解決を試みる。情報は Dl_info 構造体に格納される。
typedef struct {
const char *dli_fname;/* Filename of defining object */
void *dli_fbase; /* Load address of that object */
const char *dli_sname;/* Name of nearest lower symbol */
void *dli_saddr; /* Exact value of nearest symbol */
} Dl_info;
dladdr ()は、エラー時には 0 を返し、成功した場合は 0 以外を返す。 関数
dlvsym
()は
dlsym
()と同じ動作をするが、バージョンの文字列を渡す引き数が
追加されている点が異なる。
例
math ライブラリをロードし、2.0 の余弦を表示する
.ft CW このプログラムを "foo.c" に書いたとすると、以下のコマンドでプログラムを
ビルドできる。
gcc -rdynamic -o foo foo.c -ldl
_init() と _fini() をエクスポートするライブラリの場合は
以下のようにしてコンパイルする必要がある。例として bar.c をコンパイルする場合:
gcc -shared -nostartfiles -o bar bar.c
注意
シンボル RTLD_DEFAULT と RTLD_NEXT は
<dlfcn.h>
で定義されており、
<dlfcn.h>
のインクルード前に _GNU_SOURCE が定義されている場合のみ有効となる。
歴史dlopen インターフェースの標準は SunOS をもとにしている。 SunOS には dladdr ()もあったが、 dlvsym ()はなかった。 準拠POSIX.1-2003 には dlclose (), dlerror (), dlopen (), dlsym ().の記載がある。 関連項目
ld
(1),
ldd
(1),
dl_iterate_phdr
(3),
ld.so
(8),
ldconfig
(8), ld.so info pages, gcc info pages, ld info pages
|
|