Class: Fiddle::Pointer (Ruby 2.3.7)
Description: Class : Fiddle::Pointer - Ruby 2.3.7

- Home
- Core 2.3.7
- Std-lib 2.3.7
- Downloads

Support for the Ruby 2.3 series has ended. See here for reference.

### Home Classes Methods

### In Files

- fiddle/closure.c

### Parent

Object

### Methods

- ::[]
- ::malloc
- ::new
- ::to_ptr
- #+
- #+@
- #-
- #-@
- #<=>
- #==
- #[]
- #[]=
- #eql?
- #free
- #free=
- #inspect
- #null?
- #ptr
- #ref
- #size
- #size=
- #to_i
- #to_int
- #to_s
- #to_str
- #to_value

### Class/Module Index

Quicksearch

- Fiddle
- Fiddle::BasicTypes
- Fiddle::CParser
- Fiddle::CStruct
- Fiddle::CStructBuilder
- Fiddle::CStructEntity
- Fiddle::CUnion
- Fiddle::CUnionEntity
- Fiddle::Closure
- Fiddle::Closure::BlockCaller
- Fiddle::CompositeHandler
- Fiddle::DLError
- Fiddle::Function
- Fiddle::Handle
- Fiddle::Importer
- Fiddle::Pointer
- Fiddle::Win32Types

No matching classes.

# Fiddle::Pointer

Fiddle::Pointer is a class to handle C pointers

### Public Class Methods

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);
            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_eFiddleError, "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);
        }
        OBJ_INFECT(ptr, val);
        if (wrap) RPTR_DATA(ptr)->wrap[0] = wrap;
        return ptr;
    }

Fiddle::Pointer.malloc(size, freefunc = nil) => fiddle pointer instance click to toggle source

Allocate `size` bytes of memory and associate it with an optional `freefunc` that will be called when the pointer is garbage collected.

`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(s,f);
        if (wrap) RPTR_DATA(obj)->wrap[1] = wrap;

        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;
    }

to_ptr(val) => cptr click to toggle source

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);
            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_eFiddleError, "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);
        }
        OBJ_INFECT(ptr, val);
        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);
    }

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);
    }

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);
    }

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);
    }

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_eFiddleError, "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_tainted_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_eFiddleError, "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;
    }

eql?(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;
    }

free => Fiddle::Function click to toggle source

Get the free function for this pointer.

Returns a new instance of Fiddle::Function.

See Fiddle::Function.new

                   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;
    }

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), data, data->ptr, data->size, 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_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_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_tainted_str_new2((char*)(data->ptr));
            break;
          case 1:
            len = NUM2INT(arg1);
            val = rb_tainted_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_tainted_str_new((char*)(data->ptr),data->size);
            break;
          case 1:
            len = NUM2INT(arg1);
            val = rb_tainted_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);
    }