共有ライブラリの動的ロードとは、共有ライブラリ内に含まれている関数を実際に利用する時点になって、初めて共有ライブラリをメモリにロードする方法です。

共有ライブラリを動的にロードするには、 dlopen 関数を使用します。

void *dlopen(const char * pathname , int mode );

引数 pathname には、ロードする共有ライブラリのパス名を指定します。絶対パス名と相対パス名のどちらで指定しても構いません。パス名ではなく、ファイル名だけを指定することもできます。ファイル名だけを指定した場合、環境変数 LD_LIBRARY_PATH に設定されたディレクトリ群から指定された共有ライブラリを探します。

引数 mode にはモードを表す識別子を指定します。

dlopenは、成功するとハンドルへのポインタを返します。失敗するとNULLを返します。

動的にロードしたライブラリに含まれる関数へのポインタを取得するには、 dlsym 関数を使用します。

void *dlsym(void * handle , const char * name );

引数 handle には、ハンドルへのポインタ(dlopenの戻り値)を指定します。

引数 name には、関数の名前を格納したバッファへのポインタを指定します。

dlsym は、成功すると関数へのポインタを返します。失敗するとNULLを返します。

ハンドルをクローズするには、 dlclose 関数を使用します。ハンドルをクローズすると、参照カウンタが減らされます。参照カウンタが0になると、ライブラリがアンロードされます。

int dlclose(void * handle );

動的ロード関数が失敗したときは、 dlerror 関数を使用することにより、エラー・メッセージを取得することができます。

char *dlerror(void);

dlerror は、成功するとエラー・メッセージ文字列が格納されたバッファへのポインタを返します。エラーが発生していない場合は、NULLを返します。

共有ライブラリを動的にロードするサンプル・ソースコードを次に示します。

void *handle;
int (*func)(int);

handle = dlopen("libsample.so", RTLD_LAZY);
if (handle != NULL) {
    func = (int (*)(int))dlsym(handle, "sample_function");
    if (func != NULL) {
        (*func)(0);
    } else {
        fprintf(stderr, "%s\n", dlerror());
    }
    dlclose(handle);
} else {
    fprintf(stderr, "%s\n", dlerror());
}
スポンサーリンク