C の関数をモジュールにインポートするためのモジュールです。
対象となるモジュールに Object#extend することで、そのモジュールにインポートできるようになります。
使いかたは fiddle や fiddle/import を参照してください。
self[name] -> Fiddle::Function|nil
[permalink][rdoc]Fiddle::Importer#extern でインポートした関数の Fiddle::Function オブジェクトを返します。
name という名前の関数が存在しない場合は nil を返します。
bind(signature, *opts) { ... } -> Fiddle::Function
[permalink][rdoc]Ruby のブロックを C の関数で wrap し、その関数をモジュールにインポートします。
これでインポートされた関数はモジュール関数として定義されます。また、Fiddle::Importer#[] で Fiddle::Function オブジェクトとして取り出すことができます。
signature で関数の名前とシネグチャを指定します。例えば "int compare(void*, void*)" のように指定します。
opts には :stdcall もしくは :cdecl を渡すことができ、呼出規約を明示することができます。
例
require 'fiddle/import' module M extend Fiddle::Importer dlload "libc.so.6" typealias "size_t", "unsigned long" extern "int qsort(void*, size_t, size_t, void*)" bind("int compare(void*, void*)"){|px, py| x = px.to_s(Fiddle::SIZEOF_INT).unpack("i!") y = py.to_s(Fiddle::SIZEOF_INT).unpack("i!") x <=> y } end data = [32, 180001, -13, -1, 0, 49].pack("i!*") M.qsort(Fiddle::Pointer[data], 6, Fiddle::SIZEOF_INT, M["compare"]) p data.unpack("i!*") # => [-13, -1, 0, 32, 49, 180001]
create_value(type, val = nil) -> Fiddle::CStruct
[permalink][rdoc]value(type, val = nil) -> Fiddle::CStruct
型が type で要素名が "value" であるような構造体を定義(Fiddle::Importer#struct)し、その構造体のメモリを Fiddle::CStruct#malloc で確保し、確保したメモリを保持しているオブジェクトを返します。
type は "int", "void*" といった文字列で型を指定します。 val に nil 以外を指定すると、確保された構造体にその値を代入します。
例
require 'fiddle/import' module M extend Fiddle::Importer end v = M.value("int", 32) p v.value # => 32 v.value = 48 p v.value # => 48
dlload(*libs) -> ()
[permalink][rdoc]C の動的ライブラリをモジュールにインポートします。
これで取り込んだライブラリの関数は Fiddle::Importer#extern でインポートできます。
複数のライブラリを指定することができます。ファイル名文字列を指定することでそのライブラリをインポートします。 Fiddle::Handle を渡すとそのハンドルが指しているライブラリをインポートします。
このメソッドは同じモジュールで2回呼ばないでください。
extern(signature, *opts) -> Fiddle::Function
[permalink][rdoc]Fiddle::Importer#dlload で取り込んだライブラリから C の関数をインポートします。
インポートした関数はそのモジュールにモジュール関数として定義されます。
signature で関数の名前とシネグチャを指定します。例えば "int strcmp(char*, char*)" のように指定することができます。
opts には :stdcall もしくは :cdecl を渡すことができ、呼出規約を明示することができます。
例
require 'fiddle/import' module M extern Fiddle::Importer dlload "libc.so.6" extern "int strcmp(char*, char*)" end M.strcmp("abc", "abc") # => 0 M.strcmp("abc", "abd") # => -1
import_symbol(name) -> Fiddle::Pointer
[permalink][rdoc]取り込んだライブラリからシンボルをインポートします。
返り値はシンボルがロードされたメモリのアドレスを持つ Fiddle::Pointer オブジェクトを返します。
sizeof(t) -> Integer
[permalink][rdoc]C における sizeof(t) の値を返します。
t が文字列の場合、その文字列が表す C の型の size が返されます。例えば、sizeof("char") は 1 を返します。 sizeof("char*") は環境によって 4 や 8 といった値を返します。
Fiddle::Importer#struct で定義した構造体クラスを渡すと、その構造体のサイズを返します。 Fiddle::Importer#union で定義した共用体クラスも同様です。
t がクラスの場合、t が to_ptr というインスタンスメソッドを持っているならば t.size を返します。
それ以外の場合は Pointer[t].size を返します。
例:
require 'fiddle/import' module M extend Fiddle::Importer Timeval = struct(["long tv_sec", "long tv_usec"]) p sizeof("char") # => 1 p sizeof("void*") # => 8 p sizeof(Timeval) # => 16 end
struct(signature) -> Class
[permalink][rdoc]C の構造体型に対応する Ruby のクラスを構築して返します。
構造体の各要素は C と似せた表記ができます。そしてそれを配列で signature に渡してデータを定義します。例えば C における
struct timeval { long tv_sec; long tv_usec; };
という構造体型に対応して
Timeval = struct(["long tv_sec", "long tv_usec"])
として構造体に対応するクラスを生成します。
このメソッドが返すクラスには以下のメソッドが定義されています
返されるクラスは Fiddle::CStruct を継承しています。詳しくはそちらを参照してください。
require 'fiddle/import' module M extend Fiddle::Importer dlload "libc.so.6" extern "int gettimeofday(void*, void*)" Timeval = struct(["long tv_sec", "long tv_usec"]) end time = M::Timeval.malloc M.gettimeofday(time, Fiddle::NULL) p time.tv_sec p time.tv_usec
typealias(new, orig) -> ()
[permalink][rdoc]extern や struct で利用する型の別名を定義します。
[SEE_ALSO] Fiddle::Importer#extern, Fiddle::Importer#sizeof, Fiddle::Importer#struct, Fiddle::Importer#union
union(signature) -> Class
[permalink][rdoc]C の共用体型に対応する Ruby のクラスを構築して返します。
共用体型を Ruby 上で定義する方法は Fiddle::Importer#struct とほぼ同様です。C における
typedef union epoll_data { void *ptr; int fd; uint32_t u32; uint64_t u64; } epoll_data_t;
は、Ruby上では
require 'fiddle/import' module M extend Fiddle::Importer dlload "libc.so.6" typealias("uint32_t", "unsigned int") typealias("uint64_t", "unsigned long long") EPollData = union(["void *ptr", "int fd", "uint32_t u32", "uint64_t u64", ]) end
となります。
返されるクラスは Fiddle::CUnion を継承しています。
1.9.x ではこのメソッドで返されるクラスは正しく動作しません。 2.0以降では修正されています。