123456789_123456789_123456789_123456789_123456789_

Class: Fiddle::Closure

Relationships & Source Files
Namespace Children
Classes:
Extension / Inclusion / Inheritance Descendants
Subclasses:
Inherits: Object
Defined in: lib/fiddle/closure.rb,
ext/fiddle/pinned.c,
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

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(ret, args, abi = Function::DEFAULT) ⇒ Closure

[ GitHub ]

  
# File '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

#initialize(object) ⇒ Pinned

Alias for Pinned#initialize.

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
[ GitHub ]

  
# 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 Attribute Details

#args (readonly)

arguments of the FFI closure

[ GitHub ]

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

attr_reader :args

#ctype (readonly)

the C type of the return of the FFI closure

[ GitHub ]

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

attr_reader :ctype

#freed?Boolean (readonly)

[ GitHub ]

  
# File 'lib/fiddle/ffi_backend.rb', line 210

def freed?
  @freed
end

Instance Method Details

#free

[ GitHub ]

  
# File 'lib/fiddle/ffi_backend.rb', line 204

def free
  return if @freed
  @function.free
  @freed = true
end

#to_i

[ GitHub ]

  
# File 'lib/fiddle/ffi_backend.rb', line 200

def to_i
  @function.to_i
end

#to_ptr

[ GitHub ]

  
# File 'lib/fiddle/ffi_backend.rb', line 196

def to_ptr
  @function
end