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