10.4 動的リンクライブラリの使用
これまで説明したC関数宣言
val = _import "" :
はの名前を持つC関数を静的にリンクする指示です. SML#は,この宣言を含むプログラムをオブジェクトファイルに コンパイルする時,C関数の名前をリンカによって解決すべき外部名として 書き出します. C関数はリンク時にSML#のオブジェクトファイルと共にリンクさ れます. 対話型モードも第14章で説明す る分割コンパイルのしくみを使って実装されているため,この宣言は対話型モー ドでも使用できます.
しかしながら,実行時にしか分からないライブラリの関数などを利用し たい場合などは,この静的なリンクは使用できません. SML#は,そのような場合も対応できる動的リンク機能を以下 のモジュールとして提供しています.
structure DynamicLink : sig
type lib
type codeptr
datatype scope = LOCAL | GLOBAL
datatype mode = LAZY | NOW
val dlopen : string -> lib
val dlopen’ : string * scope * mode -> lib
val dlsym : lib * string -> codeptr
val dlclose : lib -> unit
end
これら関数は,Unix系OSで提供されている同名のシステムサービスと同 等の機能をもっています.
-
•
dlopenは,共有ライブラリの名前を受け取り,共有ライブラリをオー プンします.
-
•
dlopen’は,より詳細なオープン機能を指定できます. scopeとmodeは,OSのシステムサービスdlopenに それぞれ RTLD_LOCAL, RTLD_GLOBALおよび RTLD_LAZY, RTLD_NOW を指定します. 詳しくは,OSのdlopen関数のマニュアルを参照ください.
-
•
dlsymは, dlopenでオープンされた共有ライブラリとライ ブラリ内の関数名を受け取り,その関数へのポインタを返します.
-
•
dlcloseは,共有ライブラリをクローズします.
dlsymで返される関数ポインタは,以下の構文によって SML#の関数に変換することができます.
: _import
は,codeptr型を持つSML#の式です. は,静的リンクを行う_import宣言で 記述する型と同一の構文によって記述されたCの型です. この式は,対応するSML#の型を持つ式となります.
動的リンクライブラリの利用手順は以下の通りです.
-
1.
C言語などで動的リンクライブラリを作成します. 例えばLinuxでgccコンパイラを用いる場合, -sharedスイッチを指定すれば作成できます.
-
2.
SML#で以下のコードを実行します.
-
(a)
dlopenでライブラリをオープンします.
-
(b)
dlsymで関数ポインタを取り出します.
-
(c)
型を指定し,C関数をSML#の変数に束縛します.
-
(a)
図10.2に動的リンクの利用例を示します. 共有ライブラリの作成はSML#によるコードの実行前であればい つでもよいので,リンク時には存在しないC関数なども,利用することができま す.
samle.cファイル:
int f(int s) {
return(s * 2); } 実行例: $ gcc -shared -o sample.so sample.c $ smlsharp SML# version 1.00 (2012-04-02 JST) for x86-linux # val lib = DynamicLink.dlopen "sample.so"; val lib = _ : lib # val fptr = DynamicLink.dlsym(lib, "f"); val fptr = ptr : unit ptr # val f = fptr : _import int -> int; val f = _ : int -> int # f 3; val it = 6 : int |