Class: Fiddle::Closure

Inherits:
Object
  • Object
show all
Defined in:
ext/fiddle/closure.c,
lib/fiddle/closure.rb,
ext/fiddle/closure.c

Overview

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

Direct Known Subclasses

BlockCaller

Defined Under Namespace

Classes: BlockCaller

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Object

call-seq: new(ret, args, abi = Fiddle::DEFAULT)

Construct a new Closure object.

  • ret is the C type to be returned

  • args is an Array of arguments, passed to the callback function

  • abi is 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.



325
326
327
328
329
330
331
332
333
334
# File 'ext/fiddle/closure.c', line 325

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);
}

Instance Attribute Details

#argsObject (readonly)

arguments of the FFI closure



34
35
36
# File 'lib/fiddle/closure.rb', line 34

def args
  @args
end

#ctypeObject (readonly)

the C type of the return of the FFI closure



31
32
33
# File 'lib/fiddle/closure.rb', line 31

def ctype
  @ctype
end

Class Method Details

.create(*args) ⇒ Object

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


16
17
18
19
20
21
22
23
24
25
26
27
# File '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

Instance Method Details

#freeObject

Free this closure explicitly. You can’t use this closure anymore.

If this closure is already freed, this does nothing.



343
344
345
346
347
348
349
350
351
352
353
# File 'ext/fiddle/closure.c', line 343

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;
}

#freed?Boolean

Whether this closure was freed explicitly.

Returns:

  • (Boolean)


355
356
357
358
359
360
361
# File 'ext/fiddle/closure.c', line 355

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;
}

#to_iObject

Returns the memory address for this closure.



336
337
338
339
340
341
# File 'ext/fiddle/closure.c', line 336

static VALUE
to_i(VALUE self)
{
    fiddle_closure *closure = get_raw(self);
    return PTR2NUM(closure->code);
}