Class: FFI::AutoPointer

Inherits:
Pointer show all
Extended by:
DataConverter
Defined in:
lib/ffi/autopointer.rb

Defined Under Namespace

Classes: Releaser

Constant Summary

Constants inherited from Pointer

Pointer::SIZE

Class Method Summary collapse

Instance Method Summary collapse

Methods included from DataConverter

from_native, native_type, to_native

Methods inherited from Pointer

#read, #read_array_of_type, #read_string, #read_string_length, #read_string_to_null, size, #to_ptr, #write, #write_array_of_type, #write_string, #write_string_length

Constructor Details

#initialize(pointer, method) ⇒ self #initialize(pointer, proc) ⇒ self #initialize(pointer) ⇒ self

Note:

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.

Note:

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

Returns a new instance of AutoPointer.

Overloads:

  • #initialize(pointer, method) ⇒ self

    The passed Method will be invoked at GC time.

    Parameters:

    • pointer (Pointer)
    • method (Method)
  • #initialize(pointer, proc) ⇒ self
    Note:

    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.

    The passed Proc will be invoked at GC time (SEE WARNING BELOW!)

    Parameters:

  • #initialize(pointer) ⇒ self

    The pointer’s release() class method will be invoked at GC time.

    Parameters:

Raises:

  • (TypeError)


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/ffi/autopointer.rb', line 70

def initialize(ptr, proc=nil)
  raise TypeError, "Invalid pointer" if ptr.nil? || !ptr.kind_of?(Pointer) ||
      ptr.kind_of?(MemoryPointer) || ptr.kind_of?(AutoPointer)
  super(ptr.type_size, ptr)

  @releaser = if proc
                if not proc.respond_to?(:call)
                  raise RuntimeError.new("proc must be callable")
                end
                Releaser.new(ptr, proc)

              else
                if not self.class.respond_to?(:release, true)
                  raise RuntimeError.new("no release method defined")
                end
                Releaser.new(ptr, self.class.method(:release))
              end

  ObjectSpace.define_finalizer(self, @releaser)
  self
end

Class Method Details

.self.from_native(ptr, ctx) ⇒ AutoPointer

Create a new AutoPointer.

Override DataConverter#from_native.

Parameters:

  • ptr (Pointer)
  • ctx

    not used. Please set nil.

Returns:



175
176
177
# File 'lib/ffi/autopointer.rb', line 175

def self.from_native(val, ctx)
  self.new(val)
end

.native_typeType::POINTER

Return native type of AutoPointer.

Override DataConverter#native_type.

Returns:

  • (Type::POINTER)

Raises:

  • (RuntimeError)

    if class does not implement a #release method



161
162
163
164
165
166
# File 'lib/ffi/autopointer.rb', line 161

def self.native_type
  if not self.respond_to?(:release, true)
    raise RuntimeError.new("no release method defined for #{self.inspect}")
  end
  Type::POINTER
end

Instance Method Details

#autorelease=(autorelease) ⇒ Boolean

Set autorelease property. See Autorelease section at Pointer.

Parameters:

  • autorelease (Boolean)

Returns:

  • (Boolean)

    autorelease

Raises:

  • (FrozenError)


101
102
103
104
# File 'lib/ffi/autopointer.rb', line 101

def autorelease=(autorelease)
  raise FrozenError.new("can't modify frozen #{self.class}") if frozen?
  @releaser.autorelease=(autorelease)
end

#autorelease?Boolean

Get autorelease property. See Autorelease section at Pointer.

Returns:

  • (Boolean)

    autorelease



108
109
110
# File 'lib/ffi/autopointer.rb', line 108

def autorelease?
  @releaser.autorelease
end

#freenil

Free the pointer.

Returns:

  • (nil)


94
95
96
# File 'lib/ffi/autopointer.rb', line 94

def free
  @releaser.free
end