class FFI::AutoPointer

Public Class Methods

Create a new AutoPointer.

Override {DataConverter#from_native}. @overload self.from_native(ptr, ctx)

@param [Pointer] ptr
@param ctx not used. Please set +nil+.

@return [AutoPointer]

# File lib/ffi/autopointer.rb, line 175
def self.from_native(val, ctx)
  self.new(val)
end

Return native type of AutoPointer.

Override {DataConverter#native_type}. @return [Type::POINTER] @raise {RuntimeError} if class does not implement a release method

# 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

@overload initialize(pointer, method)

@param pointer [Pointer]
@param method [Method]
@return [self]
The passed Method will be invoked at GC time.

@overload initialize(pointer, proc)

@param pointer [Pointer]
@return [self]
The passed Proc will be invoked at GC time (SEE WARNING BELOW!)
@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.

@overload initialize(pointer)

@param pointer [Pointer]
@return [self]
The pointer's release() class method will be invoked at GC time.

@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 {AutoPointer}, and override
#release, which by default does nothing.
Calls superclass method
# 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

Public Instance Methods

@param [Boolean] autorelease @return [Boolean] autorelease Set autorelease property. See {Pointer Autorelease section at Pointer}.

# 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

@return [Boolean] autorelease Get autorelease property. See {Pointer Autorelease section at Pointer}.

# File lib/ffi/autopointer.rb, line 108
def autorelease?
  @releaser.autorelease
end

@return [nil] Free the pointer.

# File lib/ffi/autopointer.rb, line 94
def free
  @releaser.free
end