共有ライブラリの動的ロード

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

dlopen

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

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

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

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

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

dlsym

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

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

handle
引数handleには、ハンドルへのポインタ(dlopenの戻り値)を指定します。
name
引数nameには、関数の名前を格納したバッファへのポインタを指定します。

dlclose

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

int dlclose(void *handle);
handle
ハンドル(dlopen関数の戻り値)を指定する。

dlerror

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

char *dlerror(void);

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

共有ライブラリを動的にロードするサンプルコード

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

#include <dlfcn.h>

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());
}