Ruby/DL は、UNIX の dlopen(3) や Windows の
LoadLibrary()
などのダイナミックリンカへのインタフェースを提供す
る。また、現在dl2のruby-1.8
版も開発されている。
通常は、DL::Importable モジュールを使用する。 これはライブラリ関数にアクセスするための高水準の関数を持っている。 あるモジュールを拡張するには以下のように DL::Importable を使用する。
require "dl/import" module LIBC extend DL::Importable end
以後、このモジュールの dlload と extern メソッドを使用できる。以下のよ うに dlload 使ってライブラリをロードし、それぞれのライブラリ関数に対し て extern を使用することでラッパーメソッドを定義する。
module LIBC extend DL::Importable dlload "libc.so.6","libm.so.6" extern "int strlen(char*)" end # Note that we should not include the module LIBC from some reason.
LIBC.strlen を使用することで、ライブラリ関数 strlen() を使用できる。与 えられた関数名の最初の文字が大文字なら、定義されるメソッド名の最初の文 字は小文字になる。
以下のように dl/struct.rb で定義される struct や union 関数を使用す ることで構造体や共用体のメモリイメージを作成することもできる。
require "dl/import" require "dl/struct" module LIBC extend DL::Importable Timeval = struct [ # define timeval structure. "long tv_sec", "long tv_uses", ] end val = LIBC::Timeval.malloc # allocate memory.
上の例で、メモリの割り当てに LIBC::Timeval.new ではなく、 LIBC::Timeval.malloc を使用していることに注意。LIBC::Timeval.new は、 作成済みの PtrData オブジェクトをラップするためのものだ。
以下のように モジュール関数 callback を使用したコールバックを定義できる。
module Foo extend DL::Importable def my_comp(str1,str2) str1 <=> str2 end COMPARE = callback "int my_comp(char*,char*)" end
ここで Foo::COMPARE は、my_comp メソッドを起動する Symbol オブジェクトだ。
DL::Importable モジュールはとても便利だ。しかし、ときにはdlsym() のよ うな低レベル関数を直接使わなければならない場面に出くわす。このような場 合には DL モジュールの関数を使用することになるだろう。これについては DL で説明する。