Class: FFI::AutoPointer

Inherits:
Pointer
  • Object
show all
Defined in:
lib/ffi/autopointer.rb,
ext/ffi_c/AutoPointer.c

Constant Summary

Constants inherited from Pointer

Pointer::NULL, Pointer::SIZE

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Pointer

#+, #==, #address, #inspect, #null?, #read_array_of_int, #read_array_of_long, #read_array_of_pointer, #read_array_of_type, #read_float, #read_int, #read_long, #read_long_long, #read_pointer, #read_string, #read_string_length, #read_string_to_null, size, #write_array_of_int, #write_array_of_long, #write_array_of_pointer, #write_array_of_type, #write_float, #write_int, #write_long, #write_long_long, #write_pointer, #write_string, #write_string_length

Constructor Details

#initialize(ptr, proc = nil, &block) ⇒ AutoPointer

call-seq:

AutoPointer.new(pointer, method)     => the passed Method will be invoked at GC time
AutoPointer.new(pointer, proc)       => the passed Proc will be invoked at GC time (SEE WARNING BELOW!)
AutoPointer.new(pointer) { |p| ... } => the passed block will be invoked at GC time (SEE WARNING BELOW!)
AutoPointer.new(pointer)             => the pointer's release() class method will be invoked at GC time

WARNING: passing a proc may cause your pointer to never be GC’d, unless you’re careful to avoid trapping a reference to the pointer in the proc. See the test specs for examples. WARNING: passing a block will cause your pointer to never be GC’d. This is bad.

Please note that the safest, and therefore preferred, calling idiom is to pass a Method as the second parameter. Example usage:

class PointerHelper
  def self.release(pointer)
    ...
  end
end

p = AutoPointer.new(other_pointer, PointerHelper.method(:release))

The above code will cause PointerHelper#release to be invoked at GC time.

The last calling idiom (only one parameter) is generally only going to be useful if you subclass AutoPointer, and override release(), which by default does nothing.

Raises:

  • (TypeError)


30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/ffi/autopointer.rb', line 30

def initialize(ptr, proc=nil, &block)
  raise TypeError, "Invalid pointer" if ptr.nil? || !ptr.kind_of?(Pointer) \
    || ptr.kind_of?(MemoryPointer) || ptr.kind_of?(AutoPointer)
  free_lambda = if proc and proc.is_a? Method
                  AutoPointer.finalize(ptr, AutoPointer.method_to_proc(proc))
                elsif proc and proc.is_a? Proc
                  AutoPointer.finalize(ptr, proc)
                else
                  AutoPointer.finalize(ptr, AutoPointer.method_to_proc(self.class.method(:release)))
                end
  self.parent = ptr
  ObjectSpace.define_finalizer(self, free_lambda)
  self
end

Class Method Details

.release(ptr) ⇒ Object



44
45
# File 'lib/ffi/autopointer.rb', line 44

def self.release(ptr)
end