Ruby 1.9.3 リファレンスマニュアル > ライブラリ一覧 > dl/importライブラリ
dl ライブラリのための高レベルインターフェースを提供するライブラリです。
通常は dl ライブラリを使わずこの dl/import ライブラリを使います。
主な使い方は dl も参照してください。
例えば与えられた長さ len の double の配列の和を計算する関数
double sum(double *arry, int len);
があったとします。これを呼び出したい場合は以下のように Array#pack を使用します。
require 'dl/import'
module M
extend DL::Importer
dlload './libsum.so'
extern 'double sum(double*, int)'
end
p M.sum([2.0, 3.0, 4.0].pack('d*'), 3) #=> 9.0
また与えられた文字列の配列 s (長さlen)の各要素の最初の文字を buf にコピーする関数
void first_char(char **s, char *buf, int len)
があったとします。これを呼び出すにも以下のように Array#pack を使用します。
require 'dl/import'
module M
extend DL::Importer
dlload './libstrfirst.so'
extern 'void first_char(char **, char *, int)'
end
buf = '111'
M.first_char(['Abc', 'Def', 'Ghi'].pack('p*'), buf, 3)
p buf #=> 'ADG'
任意のクラスの Ruby オブジェクトをコールバックへ渡したい場合は DL.#dlwrap を使って ポインタ(整数)へ変換してから関数に渡し、コールバックの方で元に戻します。
例えば libc の qsort を使って Ruby の Time の配列をソートするには以下のようにします。
require 'dl/import'
module M
extend DL::Importer
dlload "libc.so.6"
QsortCallback = bind("void *qsort_callback(void*, void*)"){|a, b|
a0 = DL.dlunwrap(a.ptr.to_i)
b0 = DL.dlunwrap(b.ptr.to_i)
a0 <=> b0
}
extern 'void qsort(void *, int, int, void *)'
end
buff = [Time.at(1), Time.now, Time.at(100), Time.at(10)]
a = buff.map{|t| DL.dlwrap(t)}.pack('l!*')
M.qsort(a, buff.size, DL::SIZEOF_VOIDP, M::QsortCallback)
p a.unpack('l!*').map{|t| DL.dlunwrap(t).to_i } #=> [1, 10, 100, 1241603848]
構造体をメンバとして持つ構造体を DL::Importer#struct を使って定義することは残念ながらできません。 自力でメンバを展開してから DL::Importer#struct を使ってください。
| DL::CStruct | C の構造体を表すクラスです。 |
| DL::CUnion | C の共用体を表すクラスです。 |
| DL::Function | Cの関数ポインタを表すクラスです。 |
| DL::Importer | C の関数をモジュールにインポートするためのモジュールです。 |
| dl | *.dllや*.soなど、ダイナミックリンクライブラリを扱うためのライブラリです。 |