次: Modules for libltdl, 上: Using 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で定義されています.
libltdlは以下の関数を提供します.
libltdlを初期化します.この関数は,libltdl使用する前に呼び出す必要があ り,複数回呼び出すことが可能です.成功したら0,それ以外ではエラーの番 号を返します.
libltdlを終了し,すべてのモジュールを閉じます.この関数は,
lt_dlinit
が正常に呼び出された回数と同じだけ呼び出されたとき, libltdlを終了するだけです.成功したら0,それ以外ではエラーの番号を返し ます.
ファイル名filenameを用いてモジュールを開き,そのハンドルを返しま す.
lt_dlopen
は,libtoolダイナミックモジュール,プリロードされ たスタティックモジュール,プログラム自身,そしてネイティブなダイナミッ クライブラリを開くことが可能です.モジュール内の未解決のシンボルは,それが依存する(まだ実装されていない) ライブラリと,前もってdlopenされたモジュールを用いて解決されます.この モジュールを使用している実行形式が
-export-dynamic
フラグでリンク されている場合,実行形式の大域的なシンボルもモジュール内の参照の解決に 使用されます.filenameが
NULL
でプログラムが-export-dynamic
や-dlopen self
を用いてリンクされている場合,lt_dlopen
はプ ログラム自身のハンドルを返し,それはそのシンボルのアクセスに使用可能で す.libltdlがライブラリを見つけられず,ファイル名filenameがディレク トリコンポーネントを持たない場合,それは,以下の検索パスを(以下の順番 で),さらにモジュールを検索します.
- ユーザ定義の検索パス: この検索パスは,関数
lt_dlsetsearchpath
,lt_dladdsearchdir
,そしてlt_dlinsertsearchdir
を用いたプ ログラムで変更可能です.- libltdlの検索パス: この検索パスは,環境変数LTDL_LIBRARY_PATHの値です.
- システムのライブラリ検索パス: システム依存のライブラリ検索パスです(例えば,Linuxでは LD_LIBRARY_PATHになります).
それぞれの検索パスは,例えば
"/usr/lib/mypkg:/lib/foo"
のように, コロンで分離された絶対的なディレクトリのリストにする必要があります.同じモジュールが複数回ロードされた場合,同じハンドルが返されます.あら ゆる原因で
lt_dlopen
が失敗した場合,NULL
が返されます.
ファイル名に異なるファイル名の拡張子を追加を試みる以外は,
lt_dlopen
と同じです.ファイル名filenameを持つファイルが見 つからない場合,libltdlは,以下の拡張子の追加を試みます.
- libtoolのアーカイブ拡張子`.la'
- ホストプラットフォームの本来のダイナミックライブラリに使用される拡張子 で,例えば,`.so',`.sl'等です.
この探索手法は,本来のダイナミックライブラリの命名規則を知らないプログ ラムが,そのようなライブラリを,libtoolモジュールと同様に,透過的に
dlopen
することを可能にするために設計されています.
モジュールhandleの参照カウントを減らします.ゼロになったり,この モジュールに依存する他のモジュールがない場合,モジュールはアンロードさ れます.成功時には0を返します.
モジュールhandle内のアドレスを返し,そこでは,ヌルで終端された文 字列nameで与えられるシンボルがロードされています.シンボルが見つ からない場合は
NULL
を返します.
libltdlのあらゆる関数から発生した最も新しいエラーを記述する,可読性の 高い文字列を返します.初期化からまたは最後に呼び出されてからエラーが発 生していない場合,
NULL
を返します.
プリロードされているモジュールpreloadedのリストを登録します. preloadedが
NULL
の場合,lt_dlpreload_default
で設定 されているリスト以外の,これまで登録されているすべてのシンボルリストが 検出されます.成功時には0を返します.
プリロードされているモジュールリストのデフォルトをpreloadedに設 定し,それは
lt_dlpreload
で検出されません.この関数は,lt_dlinit
を使用して初期化されるためにlibltdlを要求しない ことと,デフォルトでプリロードされるモジュールを登録するためにプログラ ムで使用できることに注意してください.この関数を直接呼び出す代わりに, ほとんどのプログラムはマクロLTDL_SET_PRELOADED_SYMBOLS
を使用し ます.成功時には0を返します.
プリロードされるシンボルのデフォルトリストを設定します.プリロードされ るlibltdlのモジュールを初期化するために,プログラムで使用した方が良い でしょう.
#include <ltdl.h> int main() { /* ... */ LTDL_SET_PRELOADED_SYMBOLS(); /* ... */ }
検索ディレクトリsearch_dirを現在のユーザ定義のライブラリ検索パス に後置します.成功時には0を返します.
検索ディレクトリsearch_dirをユーザ定義のライブラリ検索パスを,ア ドレスbeforeで始まる項目の直前に挿入します.beforeが `NULL'の場合,
lt_dladdsearchdir
が呼び出されたのと同様に後 置します.成功時には0を返します.
現在のユーザ定義のライブラリ検索パスをsearch_pathで置換し,それ はコロンで分けられた絶対的なディレクトリのリストにする必要があります. 成功時には0を返します.
アプリケーションによっては,既知の名前でモジュールを個別にロードしたく なく,むしろディレクトリの組みからすべてのモジュールを見つけたり,初期 化中にすべてロードしたいかもしれません.この関数を用いると,libltdlに 候補となるsearch_path内のコロンで分離されたディレクトリリストを 走査させ,それらを独自のコールバック関数funcに渡すdataと併 せて渡すことが可能です.seach_pathが`NULL'の場合,
lt_dlopen
が調査する標準的な場所をすべて検索します.この関数は, これらの呼び出しの一つでもゼロ以外の値が返されるまで,またはファイルが 亡くなるまで,search_pathで見つかったそれぞれのファイルに対し, funcを呼び出し続けます.`lt_dlforeachfile'は最後の funcの呼び出しの返り値を返します.例えば,最初のベクトル(配列)のアドレスを保持しているdataを使用し ているファイルの,順番になっているargvのようなベクトル(配列)を構 築するために,funcを定義することも可能です.
モジュールを`lt_dlclose'できないように印を付けます.モジュールが プロジェクトの中心部の機能を実装している場合,削除されるとコードが壊れ るので,これは役に立つはずです.成功すると0を返します.
実行しているバイナリに対するhandleを取得するために `lt_dlopen (NULL)'を使用する場合,そのハンドルは常駐しているよう な印が常に付き,したがってうまく`lt_dlclose'することができません.