ダイナミックリンクの議論では,その用語が二つの異なる概念を述べる ときに使用されるので,混乱することがあります.
dlopen
(8)のような関数の呼び出しで,
それは,ユーザが指定したモジュールを実行時に任意にロードします.この形
式のダイナミックリンクは,アプリケーションで明示的に制御されます.
混乱を軽減するため,このマニュアルは二番目の形式のダイナミックリンクを dlopenモジュールとして述べることにします.
dlopenモジュールの主な利点は,プログラムを拡張するために,インタプリタ 言語を使用するのではなく,コンパイルされたオブジェクトコードにアクセス する能力です.実際,dlopenは,言語を拡張する効果的な方法を提供するため, インタプリタ言語でよく使用されます.
バージョン1.5の現在は,libtoolはdlopenされるモジュールのサ ポートを提供します.しかし,パッケージがそのようなサポートを行うことを, `configure.in'で,マクロ`AC_LIBTOOL_DLOPEN'を使用して指示し た方が良いでしょう.このマクロが使用されない(または `AC_PROG_LIBTOOL'の後で使用される)場合,libtoolはdlopenメ カニズムが利用不可能と仮定し,シミュレーションを試みます.
この章ではdlopenでアクセス可能なモジュールを生成するため,dlopenアプリ ケーション開発者がlibtoolを使用する方法を議論します.
オペレーティングシステムには,プログラムシンボルを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$
libtoolは,dlopenするlibtoolオブジェクトとlibtoolライブラリファイルに
対し,たとえdlopen
とdlsym
関数が無いプラットフォー
ムでも,そのシンボルが解決できるように,特別のサポートを提供します.
"laziness"の増加順にプログラムにコードをロードする,以下の別の方法を 考慮します.
libtoolは,コンパイル時にオブジェクトファイルをプログラムにリンクし, プログラムのシンボルテーブルを表現するデータ構造を作成することで,スタ ティックなプラットフォームで`-dlopen'オプションをエミュレートしま す.
この特徴を使用するため,プログラムのリンク時(see section リンクモード)に `-dlopen'や`-dlpreopen'フラグを使用することで,アプリケーショ ンでdlopenしたいオブジェクトを宣言する必要があります.
"fprintf"
のような,シンボル名のNULL終端されて
いる文字列です.address属性は,&fprintf
のような対応するオ
ブジェクトへの一般的なポインタです.
0
の
addressがあり,このファイルからエクスポートされるすべてのシンボ
ルが続きます.実行形式自身に対し,特別の名前@PROGRAM@が使用されます.
最後の要素は,nameと0
のaddressを持ちます.
ドル記号のような,ANSI Cでは有効ではない識別子を許可するコンパイラもあ ります.libtoolはANSI Cで有効なシンボル(最初がASCII文字またはアンダー スコアで,ゼロ個以上のASCII文字,数字,そしてアンダースコアが続くもの) のみ認識するので,非ASCIIシンボルはlt_preloaded_symbolsに出現し ません.
`-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モジュールを
見つけることを保証します.
以下の問題は,libtoolのdlopenサポートを使用しても解決しません.
dlopen
ファミリーのラッパー関数を書くことを必要とし,それは,与
えられたプラットフォームでdlopenがサポートされていないまたは利用不可能
なときの,パッケージ特有のトリックです.
dlopen
ファミリーの実装には大きな違いがあります.同じ関数
名を用いないプラットフォーム(特にHP-UXではshl_load
ファミリーを
用います)さえ存在します.
dlopen
に渡す正しいモジュール名を発見
するために,カスタムの検索関数を書く必要があります.
Go to the first, previous, next, last section, table of contents.