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字节。
当使用len
时len
将返回一串字节。
请参阅#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
以字符串形式返回指针内容。
当不使用参数调用时,此方法将返回具有此指针大小长度的内容。
当使用len
时len
将返回一串字节。
请参阅#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
}