要約
fiddle ライブラリのための高レベルインターフェースを提供するライブラリです。
通常は fiddle ライブラリを使わずこの fiddle/import ライブラリを使います。
主な使い方は fiddle も参照してください。
高度な使用法
○○の配列を関数に渡したい
例えば与えられた長さ len の double の配列の和を計算する関数
double sum(double *arry, int len);
があったとします。これを呼び出したい場合は以下のように Array#pack を使用します。
require 'fiddle/import'
module M
extend Fiddle::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 'fiddle/import'
module M
extend Fiddle::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 のオブジェクトをコールバックに渡したい
任意のクラスの Ruby オブジェクトをコールバックへ渡したい場合は Fiddle.#dlwrap を使ってポインタ(整数)へ変換してから関数に渡し、コールバックの方で元に戻します。
例えば libc の qsort を使って Ruby の Time の配列をソートするには以下のようにします。
require 'fiddle/import'
module M
extend Fiddle::Importer
dlload "libc.so.6"
QsortCallback = bind("void *qsort_callback(void*, void*)"){|a, b|
a0 = Fiddle.dlunwrap(a.ptr.to_i)
b0 = Fiddle.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| Fiddle.dlwrap(t)}.pack('l!*')
M.qsort(a, buff.size, Fiddle::SIZEOF_VOIDP, M::QsortCallback)
p a.unpack('l!*').map{|t| Fiddle.dlunwrap(t).to_i } #=> [1, 10, 100, 1241603848]
複雑な構造体を定義したい
構造体をメンバとして持つ構造体を Fiddle::Importer#struct を使って定義することは残念ながらできません。自力でメンバを展開してから Fiddle::Importer#struct を使ってください。
クラス
| Fiddle::CStruct | C の構造体を表すクラスです。 |
| Fiddle::CUnion | C の共用体を表すクラスです。 |
モジュール
| Fiddle::Importer | C の関数をモジュールにインポートするためのモジュールです。 |
同時にrequireされるライブラリ
| fiddle | *.dllや*.soなど、ダイナミックリンクライブラリを扱うためのライブラリです。 |