Class: Fiddle::Closure

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

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.



350
351
352
353
354
355
356
357
358
359
# File 'ext/fiddle/closure.c', line 350

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 'ext/fiddle/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 'ext/fiddle/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 '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

Instance Method Details

#freeObject

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

If this closure is already freed, this does nothing.



368
369
370
371
372
373
374
375
376
377
378
# File 'ext/fiddle/closure.c', line 368

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)


380
381
382
383
384
385
386
# File 'ext/fiddle/closure.c', line 380

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.



361
362
363
364
365
366
# File 'ext/fiddle/closure.c', line 361

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