Fiddle::Closure
class Fiddle::Closure
Parent:Object
描述
一个FFI封闭包装器,用于处理回调。
例
closure = Class.new(Fiddle::Closure) {
def call
10
end
}.new(Fiddle::TYPE_INT, [])
#=> #<#<Class:0x0000000150d308>:0x0000000150d240>
func = Fiddle::Function.new(closure, [], Fiddle::TYPE_INT)
#=> #<Fiddle::Function:0x00000001516e58>
func.call
#=> 10
属性
argsR
FFI关闭的论点
ctypeR
FFI封闭返回的C类型
公共类方法
new(ret, args, abi = Fiddle::DEFAULT) Show source
构建一个新的Closure对象。
ret
是要返回的C类型
args
是一个传递给回调函数的参数数组
abi
是关闭的abi
如果在准备ffi_cif或ffi_prep_closure时出错,则会引发RuntimeError。
static VALUE
initialize(int rbargc, VALUE argv[], VALUE self)
{
VALUE ret;
VALUE args;
VALUE abi;
fiddle_closure * cl;
ffi_cif * cif;
ffi_closure *pcl;
ffi_status result;
int i, argc;
if (2 == rb_scan_args(rbargc, argv, "21", &ret, &args, &abi))
abi = INT2NUM(FFI_DEFAULT_ABI
Check_Type(args, T_ARRAY
argc = RARRAY_LENINT(args
TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, cl
cl->argv = (ffi_type **)xcalloc(argc + 1, sizeof(ffi_type *)
for (i = 0; i < argc; i++) {
int type = NUM2INT(RARRAY_AREF(args, i)
cl->argv[i] = INT2FFI_TYPE(type
}
cl->argv[argc] = NULL;
rb_iv_set(self, "@ctype", ret
rb_iv_set(self, "@args", args
cif = &cl->cif;
pcl = cl->pcl;
result = ffi_prep_cif(cif, NUM2INT(abi), argc,
INT2FFI_TYPE(NUM2INT(ret)),
cl->argv
if (FFI_OK != result)
rb_raise(rb_eRuntimeError, "error prepping CIF %d", result
#if USE_FFI_CLOSURE_ALLOC
result = ffi_prep_closure_loc(pcl, cif, callback,
(void *)self, cl->code
#else
result = ffi_prep_closure(pcl, cif, callback, (void *)self
cl->code = (void *)pcl;
i = mprotect(pcl, sizeof(*pcl), PROT_READ | PROT_EXEC
if (i) {
rb_sys_fail("mprotect"
}
#endif
if (FFI_OK != result)
rb_raise(rb_eRuntimeError, "error prepping closure %d", result
return self;
}
公共实例方法
to_i() Show source
返回此闭包的内存地址
static VALUE
to_i(VALUE self)
{
fiddle_closure * cl;
void *code;
TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, cl
code = cl->code;
return PTR2NUM(code
}