Fiddle::Pointer
is a class to handle C pointers
Fiddle::Pointer[val] → cptr click to toggle source
to_ptr(val) → cptr
Get the underlying pointer for ruby object val
and return it as a Fiddle::Pointer
object.
static VALUE rb_fiddle_ptr_s_to_ptr(VALUE self, VALUE val) { VALUE ptr, wrap = val, vptr; if (RTEST(rb_obj_is_kind_of(val, rb_cIO))){ rb_io_t *fptr; FILE *fp; GetOpenFile(val, fptr); fp = rb_io_stdio_file(fptr); ptr = rb_fiddle_ptr_new(fp, 0, NULL); } else if (RTEST(rb_obj_is_kind_of(val, rb_cString))){ char *str = StringValuePtr(val); wrap = val; ptr = rb_fiddle_ptr_new(str, RSTRING_LEN(val), NULL); } else if ((vptr = rb_check_funcall(val, id_to_ptr, 0, 0)) != Qundef){ if (rb_obj_is_kind_of(vptr, rb_cPointer)){ ptr = vptr; wrap = 0; } else{ rb_raise(rb_eFiddleDLError, "to_ptr should return a Fiddle::Pointer object"); } } else{ VALUE num = rb_Integer(val); if (num == val) wrap = 0; ptr = rb_fiddle_ptr_new(NUM2PTR(num), 0, NULL); } if (wrap) RPTR_DATA(ptr)->wrap[0] = wrap; return ptr; }
Fiddle::Pointer.malloc(size, freefunc = nil) → fiddle pointer instance click to toggle source
Fiddle::Pointer.malloc(size, freefunc) { |pointer| ... } → ...
Examples¶ ↑# Automatically freeing the pointer when the block is exited - recommended Fiddle::Pointer.malloc(size, Fiddle::RUBY_FREE) do |pointer| ... end # Manually freeing but relying on the garbage collector otherwise pointer = Fiddle::Pointer.malloc(size, Fiddle::RUBY_FREE) ... pointer.call_free # Relying on the garbage collector - may lead to unlimited memory allocated before freeing any, but safe pointer = Fiddle::Pointer.malloc(size, Fiddle::RUBY_FREE) ... # Only manually freeing pointer = Fiddle::Pointer.malloc(size) begin ... ensure Fiddle.free pointer end # No free function and no call to free - the native memory will leak if the pointer is garbage collected pointer = Fiddle::Pointer.malloc(size) ...
Allocate size
bytes of memory and associate it with an optional freefunc
.
If a block is supplied, the pointer will be yielded to the block instead of being returned, and the return value of the block will be returned. A freefunc
must be supplied if a block is.
If a freefunc
is supplied it will be called once, when the pointer is garbage collected or when the block is left if a block is supplied or when the user calls call_free
, whichever happens first. freefunc
must be an address pointing to a function or an instance of Fiddle::Function
.
static VALUE rb_fiddle_ptr_s_malloc(int argc, VALUE argv[], VALUE klass) { VALUE size, sym, obj, wrap = 0; long s; freefunc_t f; switch (rb_scan_args(argc, argv, "11", &size, &sym)) { case 1: s = NUM2LONG(size); f = NULL; break; case 2: s = NUM2LONG(size); f = get_freefunc(sym, &wrap); break; default: rb_bug("rb_fiddle_ptr_s_malloc"); } obj = rb_fiddle_ptr_malloc(klass, s,f); if (wrap) RPTR_DATA(obj)->wrap[1] = wrap; if (rb_block_given_p()) { if (!f) { rb_raise(rb_eArgError, "a free function must be supplied to Fiddle::Pointer.malloc when it is called with a block"); } return rb_ensure(rb_yield, obj, rb_fiddle_ptr_call_free, obj); } else { return obj; } }
Fiddle::Pointer.new(address) → fiddle_cptr click to toggle source
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.
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); } data->wrap[0] = wrap; data->wrap[1] = funcwrap; data->ptr = p; data->size = s; data->free = f; } return Qnil; }
Fiddle::Pointer[val] → cptr click to toggle source
to_ptr(val) → cptr
Get the underlying pointer for ruby object val
and return it as a Fiddle::Pointer
object.
static VALUE rb_fiddle_ptr_s_to_ptr(VALUE self, VALUE val) { VALUE ptr, wrap = val, vptr; if (RTEST(rb_obj_is_kind_of(val, rb_cIO))){ rb_io_t *fptr; FILE *fp; GetOpenFile(val, fptr); fp = rb_io_stdio_file(fptr); ptr = rb_fiddle_ptr_new(fp, 0, NULL); } else if (RTEST(rb_obj_is_kind_of(val, rb_cString))){ char *str = StringValuePtr(val); wrap = val; ptr = rb_fiddle_ptr_new(str, RSTRING_LEN(val), NULL); } else if ((vptr = rb_check_funcall(val, id_to_ptr, 0, 0)) != Qundef){ if (rb_obj_is_kind_of(vptr, rb_cPointer)){ ptr = vptr; wrap = 0; } else{ rb_raise(rb_eFiddleDLError, "to_ptr should return a Fiddle::Pointer object"); } } else{ VALUE num = rb_Integer(val); if (num == val) wrap = 0; ptr = rb_fiddle_ptr_new(NUM2PTR(num), 0, NULL); } if (wrap) RPTR_DATA(ptr)->wrap[0] = wrap; return ptr; }Public Instance Methods
ptr + n → new cptr click to toggle source
Returns a new pointer instance that has been advanced n
bytes.
static VALUE rb_fiddle_ptr_plus(VALUE self, VALUE other) { void *ptr; long num, size; ptr = rb_fiddle_ptr2cptr(self); size = RPTR_DATA(self)->size; num = NUM2LONG(other); return rb_fiddle_ptr_new((char *)ptr + num, size - num, 0); }
+@()
Returns a new Fiddle::Pointer
instance that is a dereferenced pointer for this pointer.
Analogous to the star operator in C.
ptr - n → new cptr click to toggle source
Returns a new pointer instance that has been moved back n
bytes.
static VALUE rb_fiddle_ptr_minus(VALUE self, VALUE other) { void *ptr; long num, size; ptr = rb_fiddle_ptr2cptr(self); size = RPTR_DATA(self)->size; num = NUM2LONG(other); return rb_fiddle_ptr_new((char *)ptr - num, size + num, 0); }
-@()
Returns a new Fiddle::Pointer
instance that is a reference pointer for this pointer.
Analogous to the ampersand operator in C.
ptr <=> other → -1, 0, 1, or nil click to toggle source
Returns -1 if less than, 0 if equal to, 1 if greater than other
.
Returns nil if ptr
cannot be compared to other
.
static VALUE rb_fiddle_ptr_cmp(VALUE self, VALUE other) { void *ptr1, *ptr2; SIGNED_VALUE diff; if(!rb_obj_is_kind_of(other, rb_cPointer)) return Qnil; ptr1 = rb_fiddle_ptr2cptr(self); ptr2 = rb_fiddle_ptr2cptr(other); diff = (SIGNED_VALUE)ptr1 - (SIGNED_VALUE)ptr2; if (!diff) return INT2FIX(0); return diff > 0 ? INT2NUM(1) : INT2NUM(-1); }
ptr == other → true or false click to toggle source
Returns true if other
wraps the same pointer, otherwise returns false.
static VALUE rb_fiddle_ptr_eql(VALUE self, VALUE other) { void *ptr1, *ptr2; if(!rb_obj_is_kind_of(other, rb_cPointer)) return Qfalse; ptr1 = rb_fiddle_ptr2cptr(self); ptr2 = rb_fiddle_ptr2cptr(other); return ptr1 == ptr2 ? Qtrue : Qfalse; }
ptr[index] → an_integer click to toggle source
ptr[start, length] → a_string
Returns integer stored at index.
If start and length are given, a string containing the bytes from start of length will be returned.
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; }
ptr[index] = int → int click to toggle source
ptr[start, length] = string or cptr or addr → string or dl_cptr or addr
Set
the value at index
to int
.
Or, set the memory at start
until length
with the contents of string
, the memory from dl_cptr
, or the memory pointed at by the memory address addr
.
static VALUE rb_fiddle_ptr_aset(int argc, VALUE argv[], VALUE self) { VALUE arg0, arg1, arg2; VALUE retval = Qnil; size_t offset, len; void *mem; 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, "21", &arg0, &arg1, &arg2) ){ case 2: offset = NUM2ULONG(arg0); ((char*)data->ptr)[offset] = NUM2UINT(arg1); retval = arg1; break; case 3: offset = NUM2ULONG(arg0); len = NUM2ULONG(arg1); if (RB_TYPE_P(arg2, T_STRING)) { mem = StringValuePtr(arg2); } else if( rb_obj_is_kind_of(arg2, rb_cPointer) ){ mem = rb_fiddle_ptr2cptr(arg2); } else{ mem = NUM2PTR(arg2); } memcpy((char *)data->ptr + offset, mem, len); retval = arg2; break; default: rb_bug("rb_fiddle_ptr_aset()"); } return retval; }
call_free → nil click to toggle source
Call the free function for this pointer. Calling more than once will do nothing. Does nothing if there is no free function attached.
static VALUE rb_fiddle_ptr_call_free(VALUE self) { struct ptr_data *pdata; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, pdata); fiddle_ptr_free_ptr(pdata); return Qnil; }
eql?(other) → true or false
Returns true if other
wraps the same pointer, otherwise returns false.
free → Fiddle::Function click to toggle source
Get the free function for this pointer.
Returns a new instance of Fiddle::Function
.
static VALUE rb_fiddle_ptr_free_get(VALUE self) { struct ptr_data *pdata; VALUE address; VALUE arg_types; VALUE ret_type; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, pdata); if (!pdata->free) return Qnil; address = PTR2NUM(pdata->free); ret_type = INT2NUM(TYPE_VOID); arg_types = rb_ary_new(); rb_ary_push(arg_types, INT2NUM(TYPE_VOIDP)); return rb_fiddle_new_function(address, arg_types, ret_type); }
free=(function) click to toggle source
Set
the free function for this pointer to function
in the given Fiddle::Function
.
static VALUE rb_fiddle_ptr_free_set(VALUE self, VALUE val) { struct ptr_data *data; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); data->free = get_freefunc(val, &data->wrap[1]); return Qnil; }
freed? → bool click to toggle source
Returns if the free function for this pointer has been called.
static VALUE rb_fiddle_ptr_freed_p(VALUE self) { struct ptr_data *pdata; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, pdata); return pdata->freed ? Qtrue : Qfalse; }
inspect click to toggle source
Returns a string formatted with an easily readable representation of the internal state of the pointer.
static VALUE rb_fiddle_ptr_inspect(VALUE self) { struct ptr_data *data; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); return rb_sprintf("#<%"PRIsVALUE":%p ptr=%p size=%ld free=%p>", RB_OBJ_CLASSNAME(self), (void *)data, data->ptr, data->size, (void *)data->free); }
null? click to toggle source
Returns true
if this is a null pointer.
static VALUE rb_fiddle_ptr_null_p(VALUE self) { struct ptr_data *data; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); return data->ptr ? Qfalse : Qtrue; }
ptr click to toggle source
Returns a new Fiddle::Pointer
instance that is a dereferenced pointer for this pointer.
Analogous to the star operator in C.
static VALUE rb_fiddle_ptr_ptr(VALUE self) { struct ptr_data *data; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); return rb_fiddle_ptr_new(*((void**)(data->ptr)),0,0); }
ref click to toggle source
Returns a new Fiddle::Pointer
instance that is a reference pointer for this pointer.
Analogous to the ampersand operator in C.
static VALUE rb_fiddle_ptr_ref(VALUE self) { struct ptr_data *data; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); return rb_fiddle_ptr_new(&(data->ptr),0,0); }
size click to toggle source
Get the size of this pointer.
static VALUE rb_fiddle_ptr_size_get(VALUE self) { return LONG2NUM(RPTR_DATA(self)->size); }
size=(size) click to toggle source
Set
the size of this pointer to size
static VALUE rb_fiddle_ptr_size_set(VALUE self, VALUE size) { RPTR_DATA(self)->size = NUM2LONG(size); return size; }
to_i click to toggle source
Returns the integer memory location of this pointer.
static VALUE rb_fiddle_ptr_to_i(VALUE self) { struct ptr_data *data; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); return PTR2NUM(data->ptr); }
to_int()
Returns the integer memory location of this pointer.
to_s → string click to toggle source
to_s(len) → string
Returns the pointer contents as a string.
When called with no arguments, this method will return the contents until the first NULL byte.
When called with len
, a string of len
bytes will be returned.
See to_str
static VALUE rb_fiddle_ptr_to_s(int argc, VALUE argv[], VALUE self) { struct ptr_data *data; VALUE arg1, val; int len; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); switch (rb_scan_args(argc, argv, "01", &arg1)) { case 0: val = rb_str_new2((char*)(data->ptr)); break; case 1: len = NUM2INT(arg1); val = rb_str_new((char*)(data->ptr), len); break; default: rb_bug("rb_fiddle_ptr_to_s"); } return val; }
to_str → string click to toggle source
to_str(len) → string
Returns the pointer contents as a string.
When called with no arguments, this method will return the contents with the length of this pointerâs size
.
When called with len
, a string of len
bytes will be returned.
See to_s
static VALUE rb_fiddle_ptr_to_str(int argc, VALUE argv[], VALUE self) { struct ptr_data *data; VALUE arg1, val; int len; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); switch (rb_scan_args(argc, argv, "01", &arg1)) { case 0: val = rb_str_new((char*)(data->ptr),data->size); break; case 1: len = NUM2INT(arg1); val = rb_str_new((char*)(data->ptr), len); break; default: rb_bug("rb_fiddle_ptr_to_str"); } return val; }
to_value click to toggle source
Cast this pointer to a ruby object.
static VALUE rb_fiddle_ptr_to_value(VALUE self) { struct ptr_data *data; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); return (VALUE)(data->ptr); }
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4