[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

9. dlopenモジュール

ダイナミックリンクの議論では,その用語が二つの異なる概念を述べる ときに使用されるので,混乱することがあります.

  1. 共有ライブラリに対しプログラムをコンパイルとリンクし,それは,ダイナミッ クリンカにより実行時に自動的に解決される.この処理では,ダイナミックリ ンクはアプリケーション透過です.

  2. アプリケーションの,dlopen(8)のような関数の呼び出しで, それは,ユーザが指定したモジュールを実行時に任意にロードします.この形 式のダイナミックリンクは,アプリケーションで明示的に制御されます.

混乱を軽減するため,このマニュアルは二番目の形式のダイナミックリンクを dlopenモジュールとして述べることにします.

dlopenモジュールの主な利点は,プログラムを拡張するために,インタプリタ 言語を使用するのではなく,コンパイルされたオブジェクトコードにアクセス する能力です.実際,dlopenは,言語を拡張する効果的な方法を提供するため, インタプリタ言語でよく使用されます.

バージョン1.5の現在は,libtoolはdlopenされるモジュールのサ ポートを提供します.しかし,パッケージがそのようなサポートを行うことを, `configure.in'で,マクロ`AC_LIBTOOL_DLOPEN'を使用して指示し た方が良いでしょう.このマクロが使用されない(または `AC_PROG_LIBTOOL'の後で使用される)場合,libtoolはdlopenメ カニズムが利用不可能と仮定し,シミュレーションを試みます.

この章ではdlopenでアクセス可能なモジュールを生成するため,dlopenアプリ ケーション開発者がlibtoolを使用する方法を議論します.


9.1 dlopenのためのモジュールのビルド

オペレーティングシステムには,プログラムシンボルをdlsym(または その等価)関数を用いてダイナミックに解決するために,特別に宣言する必要 があるものもあります.

libtoolは,`-export-dynamic'と`-module'リンクフラグを提供し (see section リンクモード),それはこの宣言を行います.他のモジュールやdlopen されているlibtoolライブラリをdlopenするアプリケーションプログラムをリ ンクする場合,これらのフラグを使用する必要があります.

例えば,後でアプリケーションにdlopenされる共有ライブラリ `libhello'をビルドしたい場合,他のリンクオプションに `-module'を加えます.

 
burger$ libtool --mode=link gcc -module -o libhello.la foo.lo \
                hello.lo -rpath /usr/local/lib -lm
burger$

実行形式からのシンボルが,dlopenしたいライブラリの未解決の参照 を満足させる必要がある場合,フラグ`-export-dynamic'を使用する必要 があります.dlopenを呼び出す実行形式をリンクするとき, `-export-dynamic' を使用してください.

 
burger$ libtool --mode=link gcc -export-dynamic -o hell-dlopener main.o
burger$

9.2 dlopen

libtoolは,dlopenするlibtoolオブジェクトとlibtoolライブラリファイルに 対し,たとえdlopendlsym関数が無いプラットフォー ムでも,そのシンボルが解決できるように,特別のサポートを提供します.

"laziness"の増加順にプログラムにコードをロードする,以下の別の方法を 考慮します.

  1. 参照するしないに関わらない,実行形式の一部となるオブジェクトファイルへ のリンクです.オブジェクトファイルが見つからない場合,リンカは実行形式 の作成を停止します.

  2. 上記のオブジェクトファイルでの未定義の参照を満足させるように,リンク時 に検索されるようにするための,リンカに対するスタティックライブラリの宣 言です.スタティックライブラリが見つからない場合,リンカは実行形式の作 成を停止します.

  3. 上記のファイルでの未定義の参照を満足させるために,実行時に検索されるよ うにするための,実行時リンクの共有ライブラリの宣言です.共有ライブラリ が見つからない場合,ダイナミックリンカは実行形式の作成を停止します.

  4. アプリケーション自身が解決することができるように,参照をダイナミックに 解決するdlopenモジュールです.モジュールを開くときエラーが発生したり, モジュールが見つからない場合,アプリケーションは壊れることなく回復しま す.

libtoolは,コンパイル時にオブジェクトファイルをプログラムにリンクし, プログラムのシンボルテーブルを表現するデータ構造を作成することで,スタ ティックなプラットフォームで`-dlopen'オプションをエミュレートしま す.

この特徴を使用するため,プログラムのリンク時(see section リンクモード)に `-dlopen'や`-dlpreopen'フラグを使用することで,アプリケーショ ンでdlopenしたいオブジェクトを宣言する必要があります.

Structure: struct lt_dlsymlist { const char *name; lt_ptr address; }

name属性は,"fprintf"のような,シンボル名のNULL終端されて いる文字列です.address属性は,&fprintfのような対応するオ ブジェクトへの一般的なポインタです.

Variable: const lt_dlsymlist * lt_preloaded_symbols

lt_symbol構造体の配列で,プログラムにリンクされる,プリロードさ れているすべてのシンボルを表現します.それぞれの`-dlpreloaded'ファ イルに対し,ファイルのnameを用いた要素と,0addressがあり,このファイルからエクスポートされるすべてのシンボ ルが続きます.実行形式自身に対し,特別の名前@PROGRAM@が使用されます. 最後の要素は,name0addressを持ちます.

ドル記号のような,ANSI Cでは有効ではない識別子を許可するコンパイラもあ ります.libtoolはANSI Cで有効なシンボル(最初がASCII文字またはアンダー スコアで,ゼロ個以上のASCII文字,数字,そしてアンダースコアが続くもの) のみ認識するので,非ASCIIシンボルはlt_preloaded_symbolsに出現し ません.


9.3 dlopenで正しい名前の検索

`-module'を用いてライブラリがリンクされた後,dlopen可能になります. 残念ながら ライブラリ名が変更されるため,パッケージでdlopenの正しいファ イルを決定する必要があります.

最も率直で柔軟な実装は,インストールされた`.la'ファイルを探し,以 下の行を検索することで実行時に決定することです.

 
# The name that we can dlopen.
dlname='dlname'

dlnameが空の場合,ライブラリはdlopenされません.それ以外では,そ れでライブラリのdlnameを与えます.そのため,ライブラリが `/usr/local/lib/libhello.la'にインストールされていて, dlnameが`libhello.so.3'の場合, `/usr/local/lib/libhello.so.3'がdlopenされます.

プログラムがこのアプローチを行っている場合,ライブラリが最終的にインス トールされるディレクトリと同じように, LD_LIBRARY_PATH(9)環境変数でリストアップされているディレクトリで 検索します.この変数(または同等物)を検索することで,インストール前でも, プログラムがlibtoolを使用してリンクし提供されているdlopenモジュールを 見つけることを保証します.


9.4 未解決のdlopenの問題

以下の問題は,libtoolのdlopenサポートを使用しても解決しません.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Akihiro Sagawa on June, 15 2005 using texi2html 1.70.