class Fiddle::Closure
Description¶ ↑
An FFI closure wrapper, for handling callbacks.
Example¶ ↑
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
Attributes
arguments of the FFI closure
the C type of the return of the FFI closure
Public Class Methods
Source
# 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
Create a new closure. If a block is given, the created closure is automatically freed after the given block is executed.
The all given arguments are passed to Fiddle::Closure.new. So using this method without block equals to Fiddle::Closure.new.
Example¶ ↑
Fiddle::Closure.create(TYPE_INT, [TYPE_INT]) do |closure| # closure is freed automatically when this block is finished. end
Source
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);
}
          Construct a new Closure object.
- 
retis the C type to be returned - 
argsis anArrayof arguments, passed to the callback function - 
abiis the abi of the closure 
If there is an error in preparing the ffi_cif or ffi_prep_closure, then a RuntimeError will be raised.
Source
# 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
Public Instance Methods
Source
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;
}
          Free this closure explicitly. You can’t use this closure anymore.
If this closure is already freed, this does nothing.
Source
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;
}
          Whether this closure was freed explicitly.
Source
static VALUE
to_i(VALUE self)
{
    fiddle_closure *closure = get_raw(self);
    return PTR2NUM(closure->code);
}
          Returns the memory address for this closure.