Class: Fiddle::Closure
Relationships & Source Files | |
Namespace Children | |
Classes:
| |
Extension / Inclusion / Inheritance Descendants | |
Subclasses:
|
|
Inherits: | Object |
Defined in: | ext/fiddle/closure.c, ext/fiddle/pinned.c, ext/fiddle/lib/fiddle/closure.rb, ext/fiddle/lib/fiddle/ffi_backend.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
Class Method Summary
-
.create(*args)
Create a new closure.
-
.new(object) ⇒ Pinned
constructor
Alias for Pinned.new.
Instance Attribute Summary
-
#args
readonly
arguments of the FFI closure.
-
#ctype
readonly
the C type of the return of the FFI closure.
-
#freed? ⇒ Boolean
readonly
Whether this closure was freed explicitly.
Instance Method Summary
-
#free
Free this closure explicitly.
- #initialize(ret, args, abi = Function::DEFAULT) ⇒ Closure constructor
-
#to_i
Returns the memory address for this closure.
- #to_ptr
Constructor Details
.new(object) ⇒ Pinned
Alias for Pinned.new.
#initialize(ret, args, abi = Function::DEFAULT) ⇒ Closure
# File 'ext/fiddle/lib/fiddle/ffi_backend.rb', line 180
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
Class Method Details
.create(*args)
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 .new. So using this method without block equals to .new.
Example
Fiddle::Closure.create(TYPE_INT, [TYPE_INT]) do |closure|
# closure is freed automatically when this block is finished.
end
Instance Attribute Details
#args (readonly)
arguments of the FFI closure
# File 'ext/fiddle/lib/fiddle/closure.rb', line 34
attr_reader :args
#ctype (readonly)
the C type of the return of the FFI closure
# File 'ext/fiddle/lib/fiddle/closure.rb', line 31
attr_reader :ctype
#freed? ⇒ Boolean
(readonly)
Whether this closure was freed explicitly.
# File 'ext/fiddle/closure.c', line 381
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; }
Instance Method Details
#free
Free this closure explicitly. You can’t use this closure anymore.
If this closure is already freed, this does nothing.
# File 'ext/fiddle/closure.c', line 369
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; }
#to_i
Returns the memory address for this closure.
# File 'ext/fiddle/closure.c', line 362
static VALUE to_i(VALUE self) { fiddle_closure *closure = get_raw(self); return PTR2NUM(closure->code); }
#to_ptr
[ GitHub ]# File 'ext/fiddle/lib/fiddle/ffi_backend.rb', line 195
def to_ptr @function end