Next: , Up: Using libltdl


10.1 プログラムでのlibltdlの使用法

libltdl APIは,強力なSolarisとLinuxのdlopenインターフェースに似ていて, それは,非常に簡単ですが強力です.

プログラムでlibltdlを使用するために,ヘッダファイルltdl.hをイン クルードする必要があります.

     #include <ltdl.h>

libltdlの前回のリリースでは,posix名前空間の慣習に違反していたシ ンボルをいくつか使用していました.これらのシンボルの使用は,現在では非 難されるので,ここで記述されるように置換されました.古い非難されそうな シンボル名に依存したコードがある場合,ltdl.hをインクルードする 前に‘LT_NON_POSIX_NAMESPACE’を定義すると,変換されたマクロが提供 されます.使用するシンボルの組が何であっても,新しいAPIは前回のものと バイナリ互換ではないので,このバージョンのlibltdlを使用するため,アプ リケーションを再コンパイルする必要があるでしょう.

libltdlがスレッドセーフでない,すなわち,マルチスレッドアプリケーショ ンは,libtoolに対しミューテックスを使用する必要があることに注意してく ださい.それは,GNU/Linuxのglibc 2.0の‘RTLD_LAZY’を用いた dlopenが(デフォルトでlibtoolを使用します),スレッドセーフではな いことが報告されていますが,この問題は,glibc 2.1でおそらく修正される でしょ.一方,‘RTLD_NOW’は,FreeBSD上のマルチスレッドアプリケーショ ンで問題が生じたと報告されています.これらの問題に関する作業は,読者の 演習として残っています.貢献は,きっと歓迎されます.

以下の型はltdl.hで定義されています.

— Type: lt_ptr

lt_ptrは,汎用ポインタです.

— Type: lt_dlhandle

lt_dlhandleはモジュール"ハンドル"です.すべてのlt_dlopenされる モジュールはそれに関連付けされたハンドルがあります.

— Type: lt_dlsymlist

lt_dlsymlistはdlpreopenされるモジュールのシンボルリストです.こ の構造体は,see Dlpreopeningで記述されます.

libltdlは以下の関数を提供します.

— Function: int lt_dlinit (void)

libltdlを初期化します.この関数は,libltdl使用する前に呼び出す必要があ り,複数回呼び出すことが可能です.成功したら0,それ以外ではエラーの番 号を返します.

— Function: int lt_dlexit (void)

libltdlを終了し,すべてのモジュールを閉じます.この関数は, lt_dlinitが正常に呼び出された回数と同じだけ呼び出されたとき, libltdlを終了するだけです.成功したら0,それ以外ではエラーの番号を返し ます.

— Function: lt_dlhandle lt_dlopen (const char *filename)

ファイル名filenameを用いてモジュールを開き,そのハンドルを返しま す.lt_dlopenは,libtoolダイナミックモジュール,プリロードされ たスタティックモジュール,プログラム自身,そしてネイティブなダイナミッ クライブラリを開くことが可能です.

モジュール内の未解決のシンボルは,それが依存する(まだ実装されていない) ライブラリと,前もってdlopenされたモジュールを用いて解決されます.この モジュールを使用している実行形式が-export-dynamicフラグでリンク されている場合,実行形式の大域的なシンボルもモジュール内の参照の解決に 使用されます.

filenameNULLでプログラムが-export-dynamic-dlopen selfを用いてリンクされている場合,lt_dlopenはプ ログラム自身のハンドルを返し,それはそのシンボルのアクセスに使用可能で す.

libltdlがライブラリを見つけられず,ファイル名filenameがディレク トリコンポーネントを持たない場合,それは,以下の検索パスを(以下の順番 で),さらにモジュールを検索します.

  1. ユーザ定義の検索パス: この検索パスは,関数lt_dlsetsearchpathlt_dladdsearchdir,そしてlt_dlinsertsearchdirを用いたプ ログラムで変更可能です.
  2. libltdlの検索パス: この検索パスは,環境変数LTDL_LIBRARY_PATHの値です.
  3. システムのライブラリ検索パス: システム依存のライブラリ検索パスです(例えば,Linuxでは LD_LIBRARY_PATHになります).

それぞれの検索パスは,例えば"/usr/lib/mypkg:/lib/foo"のように, コロンで分離された絶対的なディレクトリのリストにする必要があります.

同じモジュールが複数回ロードされた場合,同じハンドルが返されます.あら ゆる原因でlt_dlopenが失敗した場合,NULLが返されます.

— Function: lt_dlhandle lt_dlopenext (const char *filename)

ファイル名に異なるファイル名の拡張子を追加を試みる以外は, lt_dlopenと同じです.ファイル名filenameを持つファイルが見 つからない場合,libltdlは,以下の拡張子の追加を試みます.

  1. libtoolのアーカイブ拡張子‘.la
  2. ホストプラットフォームの本来のダイナミックライブラリに使用される拡張子 で,例えば,‘.so’,‘.sl’等です.

この探索手法は,本来のダイナミックライブラリの命名規則を知らないプログ ラムが,そのようなライブラリを,libtoolモジュールと同様に,透過的に dlopenすることを可能にするために設計されています.

— Function: int lt_dlclose (lt_dlhandle handle)

モジュールhandleの参照カウントを減らします.ゼロになったり,この モジュールに依存する他のモジュールがない場合,モジュールはアンロードさ れます.成功時には0を返します.

— Function: lt_ptr lt_dlsym (lt_dlhandle handle, const char *name)

モジュールhandle内のアドレスを返し,そこでは,ヌルで終端された文 字列nameで与えられるシンボルがロードされています.シンボルが見つ からない場合はNULLを返します.

— Function: const char * lt_dlerror (void)

libltdlのあらゆる関数から発生した最も新しいエラーを記述する,可読性の 高い文字列を返します.初期化からまたは最後に呼び出されてからエラーが発 生していない場合,NULLを返します.

— Function: int lt_dlpreload (const lt_dlsymlist *preloaded)

プリロードされているモジュールpreloadedのリストを登録します. preloadedNULLの場合,lt_dlpreload_defaultで設定 されているリスト以外の,これまで登録されているすべてのシンボルリストが 検出されます.成功時には0を返します.

— Function: int lt_dlpreload_default (const lt_dlsymlist *preloaded)

プリロードされているモジュールリストのデフォルトをpreloadedに設 定し,それはlt_dlpreloadで検出されません.この関数は, lt_dlinitを使用して初期化されるためにlibltdlを要求しない ことと,デフォルトでプリロードされるモジュールを登録するためにプログラ ムで使用できることに注意してください.この関数を直接呼び出す代わりに, ほとんどのプログラムはマクロLTDL_SET_PRELOADED_SYMBOLSを使用し ます.

成功時には0を返します.

— Macro: LTDL_SET_PRELOADED_SYMBOLS

プリロードされるシンボルのデフォルトリストを設定します.プリロードされ るlibltdlのモジュールを初期化するために,プログラムで使用した方が良い でしょう.

          #include <ltdl.h>
          
          int main() {
            /* ... */
            LTDL_SET_PRELOADED_SYMBOLS();
            /* ... */
          }
— Function: int lt_dladdsearchdir (const char *search_dir)

検索ディレクトリsearch_dirを現在のユーザ定義のライブラリ検索パス に後置します.成功時には0を返します.

— Function: int lt_dlinsertsearchdir (const char *before, const char *search_dir)

検索ディレクトリsearch_dirをユーザ定義のライブラリ検索パスを,ア ドレスbeforeで始まる項目の直前に挿入します.beforeが ‘NULL’の場合,lt_dladdsearchdirが呼び出されたのと同様に後 置します.成功時には0を返します.

— Function: int lt_dlsetsearchpath (const char *search_path)

現在のユーザ定義のライブラリ検索パスをsearch_pathで置換し,それ はコロンで分けられた絶対的なディレクトリのリストにする必要があります. 成功時には0を返します.

— Function: const char * lt_dlgetsearchpath (void)

現在のユーザ定義のライブラリ検索パスを返します.

— Function: int lt_dlforeachfile (const char *search_path, int (*func) (const char *filename, lt_ptr data), lt_ptr data)

アプリケーションによっては,既知の名前でモジュールを個別にロードしたく なく,むしろディレクトリの組みからすべてのモジュールを見つけたり,初期 化中にすべてロードしたいかもしれません.この関数を用いると,libltdlに 候補となるsearch_path内のコロンで分離されたディレクトリリストを 走査させ,それらを独自のコールバック関数funcに渡すdataと併 せて渡すことが可能です.seach_pathが‘NULL’の場合, lt_dlopenが調査する標準的な場所をすべて検索します.この関数は, これらの呼び出しの一つでもゼロ以外の値が返されるまで,またはファイルが 亡くなるまで,search_pathで見つかったそれぞれのファイルに対し, funcを呼び出し続けます.‘lt_dlforeachfile’は最後の funcの呼び出しの返り値を返します.

例えば,最初のベクトル(配列)のアドレスを保持しているdataを使用し ているファイルの,順番になっているargvのようなベクトル(配列)を構 築するために,funcを定義することも可能です.

— Function: int lt_dlmakeresident (lt_dlhandle handle)

モジュールを‘lt_dlclose’できないように印を付けます.モジュールが プロジェクトの中心部の機能を実装している場合,削除されるとコードが壊れ るので,これは役に立つはずです.成功すると0を返します.

実行しているバイナリに対するhandleを取得するために ‘lt_dlopen (NULL)’を使用する場合,そのハンドルは常駐しているよう な印が常に付き,したがってうまく‘lt_dlclose’することができません.

— Function: int lt_dlisresident (lt_dlhandle handle)

特定のモジュールが常駐しているように印が付いているかどうか調査し,その 場合は1を返し,それ以外では0を返します.この関数の実行中にエラーがある 場合, -1 が返され,lt_dlerrorを用いて回収されるエラーメッセー ジが設定されます.

— Variable: lt_ptr (*) (size_t size) lt_dlmalloc
— Variable: void (*) (lt_ptr ptr) lt_dlfree

これらの変数は,デフォルトでmallocfreeに設定されますが, 同等の機能を提供する他の関数に設定可能です.しかし, lt_dlpreopen_defaultやマクロLTDL_SET_PRELOADED_SYMBOLS以 外のあらゆるlibltdl関数の呼び出し後に,その値を編集すべきではありませ ん.