Class: Fiddle::Closure
- Inherits:
-
Object
- Object
- Fiddle::Closure
- Defined in:
- ext/fiddle/closure.c,
lib/fiddle/closure.rb,
lib/fiddle/ffi_backend.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
Defined Under Namespace
Classes: BlockCaller
Instance Attribute Summary collapse
-
#args ⇒ Object
readonly
arguments of the FFI closure.
-
#ctype ⇒ Object
readonly
the C type of the return of the FFI closure.
Class Method Summary collapse
-
.create(*args) ⇒ Object
Create a new closure.
Instance Method Summary collapse
-
#free ⇒ Object
Free this closure explicitly.
-
#freed? ⇒ Boolean
Whether this closure was freed explicitly.
-
#initialize(*args) ⇒ Object
constructor
call-seq: new(ret, args, abi = Fiddle::DEFAULT).
-
#to_i ⇒ Object
Returns the memory address for this closure.
- #to_ptr ⇒ Object
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.
351 352 353 354 355 356 357 358 359 360 361 362 363 364 |
# File 'ext/fiddle/closure.c', line 351 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 |
Instance Attribute Details
#args ⇒ Object (readonly)
arguments of the FFI closure
34 35 36 |
# File 'lib/fiddle/closure.rb', line 34 def args @args end |
#ctype ⇒ Object (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
#free ⇒ Object
Free this closure explicitly. You can’t use this closure anymore.
If this closure is already freed, this does nothing.
369 370 371 372 373 |
# File 'ext/fiddle/closure.c', line 369 def free return if @freed @function.free @freed = true end |
#freed? ⇒ Boolean
Whether this closure was freed explicitly.
381 382 383 |
# File 'ext/fiddle/closure.c', line 381 def freed? @freed end |
#to_i ⇒ Object
Returns the memory address for this closure.
362 363 364 |
# File 'ext/fiddle/closure.c', line 362 def to_i @function.to_i end |
#to_ptr ⇒ Object
196 197 198 |
# File 'lib/fiddle/ffi_backend.rb', line 196 def to_ptr @function end |