Ruby 2.4

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 }