class Fiddle::Closure
描述¶ ↑
用于处理回调的 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
属性
FFI 闭包的参数
FFI 闭包返回的 C 类型
公共类方法
源代码
# File ext/fiddle/lib/fiddle/closure.rb, line 16 def create(*args) if block_given? closure = new(*args) begin yield(closure) ensure closure.free end else new(*args) end end
创建一个新的闭包。如果给定了代码块,则在执行给定代码块后会自动释放创建的闭包。
所有给定的参数都将传递给 Fiddle::Closure.new
。因此,不使用代码块调用此方法等同于 Fiddle::Closure.new
。
示例¶ ↑
Fiddle::Closure.create(TYPE_INT, [TYPE_INT]) do |closure| # closure is freed automatically when this block is finished. end
源代码
static VALUE initialize(int argc, VALUE *argv, VALUE self) { initialize_data data; data.self = self; data.argc = argc; data.argv = argv; return rb_rescue(initialize_body, (VALUE)&data, initialize_rescue, (VALUE)&data); }
构造一个新的 Closure
对象。
-
ret
是要返回的 C 类型 -
args
是传递给回调函数的参数的Array
-
abi
是闭包的 abi
如果在准备 ffi_cif 或 ffi_prep_closure 时出现错误,则会引发 RuntimeError
。
源代码
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 181 def initialize(ret, args, abi = Function::DEFAULT) raise TypeError.new "invalid argument types" unless args.is_a?(Array) @ctype, @args = ret, args ffi_args = @args.map { |t| Fiddle::FFIBackend.to_ffi_type(t) } if ffi_args.size == 1 && ffi_args[0] == FFI::Type::Builtin::VOID ffi_args = [] end return_type = Fiddle::FFIBackend.to_ffi_type(@ctype) raise "#{self.class} must implement #call" unless respond_to?(:call) callable = method(:call) @function = FFI::Function.new(return_type, ffi_args, callable, convention: abi) @freed = false end
公共实例方法
源代码
static VALUE closure_free(VALUE self) { fiddle_closure *closure; TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, closure); if (closure) { dealloc(closure); RTYPEDDATA_DATA(self) = NULL; } return RUBY_Qnil; }
显式释放此闭包。您不能再使用此闭包。
如果此闭包已被释放,则此操作不执行任何操作。
源代码
static VALUE closure_freed_p(VALUE self) { fiddle_closure *closure; TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, closure); return closure ? RUBY_Qfalse : RUBY_Qtrue; }
此闭包是否已被显式释放。
源代码
static VALUE to_i(VALUE self) { fiddle_closure *closure = get_raw(self); return PTR2NUM(closure->code); }
返回此闭包的内存地址。