Class: Fiddle::Pointer
Relationships & Source Files | |
Namespace Children | |
Modules:
| |
Extension / Inclusion / Inheritance Descendants | |
Subclasses:
|
|
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
FFI::DataConverter
|
|
Inherits: | Object |
Defined in: | ext/fiddle/pointer.c, ext/fiddle/pointer.c, lib/fiddle/ffi_backend.rb |
Overview
Pointer
is a class to handle C pointers
Class Method Summary
Instance Attribute Summary
- #ffi_ptr readonly
- #free rw
- #free=(free) rw
- #freed? ⇒ Boolean readonly
- #null? ⇒ Boolean readonly
- #size rw
- #size=(size) rw
Instance Method Summary
- #+(delta)
- #+@
- #-(delta)
- #-@
- #<=>(other)
- #==(other)
-
#[](index) ⇒ Integer
Returns integer stored at index.
- #[]=(*args, value)
- #call_free
- #eql?(other) ⇒ Boolean
-
#new(address) ⇒ fiddle_cptr
constructor
Create a new pointer to
address
with an optional #size andfreefunc
. - #inspect
- #ptr
- #ref
- #to_i (also: #to_int)
-
#to_int
Alias for #to_i.
- #to_ptr
-
#to_s(len = nil)
without 0.
- #to_str(len = nil)
- #to_value
Constructor Details
.new(addr, size = nil, free = nil) ⇒ Pointer
# File 'lib/fiddle/ffi_backend.rb', line 300
def initialize(addr, size = nil, free = nil) ptr = if addr.is_a?(FFI::Pointer) addr elsif addr.is_a?(Integer) FFI::Pointer.new(addr) elsif addr.respond_to?(:to_ptr) fiddle_ptr = addr.to_ptr if fiddle_ptr.is_a?(Pointer) fiddle_ptr.ffi_ptr elsif fiddle_ptr.is_a?(FFI::AutoPointer) addr.ffi_ptr elsif fiddle_ptr.is_a?(FFI::Pointer) fiddle_ptr else raise DLError.new("to_ptr should return a Fiddle::Pointer object, was #{fiddle_ptr.class}") end elsif addr.is_a?(IO) raise NotImplementedError, "IO ptr isn't supported" else FFI::Pointer.new(Integer(addr)) end @size = size ? size : ptr.size @free = free @ffi_ptr = ptr @freed = false end
#new(address) ⇒ fiddle_cptr
#new(address, size) ⇒ fiddle_cptr
#new(address, size, freefunc) ⇒ fiddle_cptr
fiddle_cptr
#new(address, size) ⇒ fiddle_cptr
#new(address, size, freefunc) ⇒ fiddle_cptr
Create a new pointer to address
with an optional #size and freefunc
.
freefunc
will be called when the instance is garbage collected.
# File 'ext/fiddle/pointer.c', line 216
static VALUE rb_fiddle_ptr_initialize(int argc, VALUE argv[], VALUE self) { VALUE ptr, sym, size, wrap = 0, funcwrap = 0; struct ptr_data *data; void *p = NULL; freefunc_t f = NULL; long s = 0; if (rb_scan_args(argc, argv, "12", &ptr, &size, &sym) >= 1) { VALUE addrnum = rb_Integer(ptr); if (addrnum != ptr) wrap = ptr; p = NUM2PTR(addrnum); } if (argc >= 2) { s = NUM2LONG(size); } if (argc >= 3) { f = get_freefunc(sym, &funcwrap); } if (p) { TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); if (data->ptr && data->free) { /* Free previous memory. Use of inappropriate initialize may cause SEGV. */ (*(data->free))(data->ptr); } RB_OBJ_WRITE(self, &data->wrap[0], wrap); RB_OBJ_WRITE(self, &data->wrap[1], funcwrap); data->ptr = p; data->size = s; data->free = f; } return Qnil; }
Class Method Details
.[](value)
Alias for .to_ptr.
# File 'lib/fiddle/ffi_backend.rb', line 274
alias [] to_ptr
.from_native(value, ctx)
[ GitHub ]# File 'lib/fiddle/ffi_backend.rb', line 236
def self.from_native(value, ctx) self.new(value) end
.malloc(size, free = nil)
[ GitHub ]# File 'lib/fiddle/ffi_backend.rb', line 338
def self.malloc(size, free = nil) if block_given? and free.nil? = "a free function must be supplied to #{self}.malloc " + "when it is called with a block" raise ArgumentError, end pointer = new(LibC.malloc(size), size, free) if block_given? begin yield(pointer) ensure pointer.call_free end else pointer end end
.read(addr, len)
[ GitHub ]# File 'lib/fiddle/ffi_backend.rb', line 269
def self.read(addr, len) FFI::Pointer.new(addr).read_bytes(len) end
.to_native(value, ctx)
[ GitHub ].to_ptr(value) Also known as: .[]
[ GitHub ]# File 'lib/fiddle/ffi_backend.rb', line 240
def self.to_ptr(value) if value.is_a?(String) cptr = Pointer.malloc(value.bytesize) cptr.ffi_ptr.put_string(0, value) cptr elsif value.is_a?(Array) raise NotImplementedError, "array ptr" elsif value.respond_to?(:to_ptr) ptr = value.to_ptr case ptr when Pointer ptr when FFI::Pointer Pointer.new(ptr) else raise DLError.new("to_ptr should return a Fiddle::Pointer object, was #{ptr.class}") end else Pointer.new(value) end end
.write(addr, bytes)
[ GitHub ]# File 'lib/fiddle/ffi_backend.rb', line 265
def self.write(addr, bytes) FFI::Pointer.new(addr).write_bytes(bytes) end
Instance Attribute Details
#ffi_ptr (readonly)
[ GitHub ]# File 'lib/fiddle/ffi_backend.rb', line 220
attr_reader :ffi_ptr
#free (rw)
[ GitHub ]# File 'lib/fiddle/ffi_backend.rb', line 369
def free @free end
#free=(free) (rw)
[ GitHub ]
#freed? ⇒ Boolean
(readonly)
[ GitHub ]
# File 'lib/fiddle/ffi_backend.rb', line 388
def freed? @freed end
#null? ⇒ Boolean
(readonly)
[ GitHub ]
# File 'lib/fiddle/ffi_backend.rb', line 357
def null? @ffi_ptr.null? end
#size (rw)
[ GitHub ]# File 'lib/fiddle/ffi_backend.rb', line 365
def size defined?(@layout) ? @layout.size : @size end
#size=(size) (rw)
[ GitHub ]Instance Method Details
#+(delta)
[ GitHub ]#+@
[ GitHub ]# File 'lib/fiddle/ffi_backend.rb', line 468
def +@ ptr end
#-(delta)
[ GitHub ]#-@
[ GitHub ]# File 'lib/fiddle/ffi_backend.rb', line 472
def -@ ref end
#<=>(other)
[ GitHub ]#==(other)
[ GitHub ]# File 'lib/fiddle/ffi_backend.rb', line 460
def ==(other) eql?(other) end
#[](index) ⇒ Integer
#[](start, length) ⇒ String
Integer
#[](start, length) ⇒ String
Returns integer stored at index.
If start and length are given, a string containing the bytes from start of length will be returned.
# File 'ext/fiddle/pointer.c', line 666
static VALUE rb_fiddle_ptr_aref(int argc, VALUE argv[], VALUE self) { VALUE arg0, arg1; VALUE retval = Qnil; size_t offset, len; struct ptr_data *data; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); if (!data->ptr) rb_raise(rb_eFiddleDLError, "NULL pointer dereference"); switch( rb_scan_args(argc, argv, "11", &arg0, &arg1) ){ case 1: offset = NUM2ULONG(arg0); retval = INT2NUM(*((char *)data->ptr + offset)); break; case 2: offset = NUM2ULONG(arg0); len = NUM2ULONG(arg1); retval = rb_str_new((char *)data->ptr + offset, len); break; default: rb_bug("rb_fiddle_ptr_aref()"); } return retval; }
#[]=(*args, value)
[ GitHub ]# File 'lib/fiddle/ffi_backend.rb', line 277
def []=(*args, value) if args.size == 2 if value.is_a?(Integer) value = self.class.new(value) end if value.is_a?(Fiddle::Pointer) value = value.to_str(args[1]) end @ffi_ptr.put_bytes(args[0], value, 0, args[1]) elsif args.size == 1 if value.is_a?(Fiddle::Pointer) value = value.to_str(args[0] + 1) else value = value.chr end @ffi_ptr.put_bytes(args[0], value, 0, 1) end rescue FFI::NullPointerError raise DLError.new("NULL pointer access") end
#call_free
[ GitHub ]
#eql?(other) ⇒ Boolean
#inspect
[ GitHub ]#ptr
[ GitHub ]#ref
[ GitHub ]#to_i Also known as: #to_int
[ GitHub ]# File 'lib/fiddle/ffi_backend.rb', line 406
def to_i ffi_ptr.to_i end
#to_int
Alias for #to_i.
# File 'lib/fiddle/ffi_backend.rb', line 409
alias to_int to_i
#to_ptr
[ GitHub ]# File 'lib/fiddle/ffi_backend.rb', line 361
def to_ptr @ffi_ptr end
#to_s(len = nil)
without 0
#to_str(len = nil)
[ GitHub ]#to_value
# File 'lib/fiddle/ffi_backend.rb', line 432
def to_value raise NotImplementedError, "to_value isn't supported" end