Ruby 2.4

Fiddle::Pointer

class Fiddle::Pointer

Parent:Object

Fiddle :: Pointer是一个处理C指针的类

公共类方法

Fiddle::Pointerval → cptr Show source

to_ptr(val) → cptr

获取ruby对象val的底层指针并将其作为Fiddle :: Pointer对象返回。

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 Show source

分配大小的内存字节并将其与可选的freefunc相关联,当指针被垃圾回收时将被调用。

freefunc 必须是指向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 Show source

new(address, size) → fiddle_cptr

new(address, size, freefunc) → fiddle_cptr

用一个可选的大小和freefunc创建一个新的地址指针。

freefunc 将在实例被垃圾收集时调用。

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 Show source

获取ruby对象的底层指针val并将其作为Fiddle :: Pointer对象返回。

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

公共实例方法

ptr + n → new cptr Show source

返回高级n字节的新指针实例。

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 Show source

返回一个新的Fiddle :: Pointer实例,该实例是此指针的解引用指针。

类似于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 Show source

返回已移回n字节的新指针实例。

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 Show source

返回一个新的Fiddle :: Pointer实例,该实例是此指针的引用指针。

类似于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 Show source

如果小于other则返回-1,如果等于则返回0,如果大于则返回1 。

如果ptr无法与other比较,则返回nil 。

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 Show source

如果other包装相同的指针,则返回true,否则返回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; }

ptrindex → an_integer Show source

ptrstart, length → a_string

返回存储在索引处的整数。

如果开始 长度 给出,含有来自字节的串开始 长度将被返回。

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

ptrindex = int → int Show source

ptrstart, length = string or cptr or addr → string or dl_cptr or addr

将值index设置为int

或者,在开始处设置内存,直到字符串的内容,dl_cptr的内存或内存地址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 Show source

如果other包装相同的指针,则返回true,否则返回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 Show source

获得这个指针的free功能。

返回Fiddle :: Function的新实例。

请参阅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) Show source

将此指针的free函数设置为给定的Fiddle :: Function中的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 Show source

返回一个字符串,其格式为指针内部状态的易读表示。

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? Show source

如果这是一个空指针,则返回true

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 Show source

返回一个新的Fiddle :: Pointer实例,该实例是此指针的解引用指针。

类似于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 Show source

返回一个新的Fiddle :: Pointer实例,该实例是此指针的引用指针。

类似于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 Show source

获取这个指针的大小。

static VALUE rb_fiddle_ptr_size_get(VALUE self) { return LONG2NUM(RPTR_DATA(self)->size }

size=(size) Show source

将此指针的大小设置为 size

static VALUE rb_fiddle_ptr_size_set(VALUE self, VALUE size) { RPTR_DATA(self)->size = NUM2LONG(size return size; }

to_i Show source

返回此指针的整数内存位置。

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 Show source

返回此指针的整数内存位置。

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 Show source

to_s(len) → string

以字符串形式返回指针内容。

当不使用参数调用时,此方法将返回内容,直到(遇到)第一个NULL字节。

当使用lenlen将返回一串字节。

请参阅#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 Show source

to_str(len) → string

以字符串形式返回指针内容。

当不使用参数调用时,此方法将返回具有此指针大小长度的内容。

当使用lenlen将返回一串字节。

请参阅#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 Show source

将此指针转换为ruby对象。

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 }