A direct accessor to a function in a C library
Example
libc_so = "/lib64/libc.so.6"
=> "/lib64/libc.so.6"
libc = DL::dlopen(libc_so)
=> #<DL::Handle:0x00000000e05b00>
@cfunc = DL::CFunc.new(libc,['strcpy'], DL::TYPE_VOIDP, 'strcpy')
=> #<DL::CFunc:0x000000012daec0 ptr=0x007f62ca5a8300 type=1 name='strcpy'>
- #
- C
- I
- L
- N
- P
- T
- W
Returns the last error for the current executing thread
Source: show
static VALUE rb_dl_get_last_error(VALUE self) { return rb_thread_local_aref(rb_thread_current(), id_last_error); }
Create a new function that points to address
with an optional
return type of type
, a name of name
and a
calltype of calltype
.
Source: show
static VALUE rb_dlcfunc_initialize(int argc, VALUE argv[], VALUE self) { VALUE addr, name, type, calltype, addrnum; struct cfunc_data *data; void *saddr; const char *sname; rb_scan_args(argc, argv, "13", &addr, &type, &name, &calltype); addrnum = rb_Integer(addr); saddr = (void*)(NUM2PTR(addrnum)); sname = NIL_P(name) ? NULL : StringValuePtr(name); TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, data); if( data->name ) xfree(data->name); data->ptr = saddr; data->name = sname ? strdup(sname) : 0; data->type = NIL_P(type) ? DLTYPE_VOID : NUM2INT(type); data->calltype = NIL_P(calltype) ? CFUNC_CDECL : SYM2ID(calltype); data->wrap = (addrnum == addr) ? 0 : addr; return Qnil; }
Returns the last win32 error for the current executing thread
Source: show
static VALUE rb_dl_get_win32_last_error(VALUE self) { return rb_thread_local_aref(rb_thread_current(), id_win32_last_error); }
Calls the function pointer passing in ary
as values to the
underlying C function. The return value depends on
the ctype.
Source: show
static VALUE rb_dlcfunc_call(VALUE self, VALUE ary) { struct cfunc_data *cfunc; int i; DLSTACK_TYPE stack[DLSTACK_SIZE]; VALUE result = Qnil; rb_secure_update(self); memset(stack, 0, sizeof(DLSTACK_TYPE) * DLSTACK_SIZE); Check_Type(ary, T_ARRAY); TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); if( cfunc->ptr == 0 ){ rb_raise(rb_eDLError, "can't call null-function"); return Qnil; } for( i = 0; i < RARRAY_LEN(ary); i++ ){ VALUE arg; if( i >= DLSTACK_SIZE ){ rb_raise(rb_eDLError, "too many arguments (stack overflow)"); } arg = rb_to_int(RARRAY_PTR(ary)[i]); rb_check_safe_obj(arg); if (FIXNUM_P(arg)) { stack[i] = (DLSTACK_TYPE)FIX2LONG(arg); } else if (RB_TYPE_P(arg, T_BIGNUM)) { #if SIZEOF_VOIDP == SIZEOF_LONG stack[i] = (DLSTACK_TYPE)rb_big2ulong_pack(arg); #else stack[i] = (DLSTACK_TYPE)rb_big2ull(arg); #endif } else { Check_Type(arg, T_FIXNUM); } } /* calltype == CFUNC_CDECL */ if( cfunc->calltype == CFUNC_CDECL #ifndef FUNC_STDCALL || cfunc->calltype == CFUNC_STDCALL #endif ){ switch( cfunc->type ){ case DLTYPE_VOID: #define CASE(n) case n: { \ DECL_FUNC_CDECL(f,void,DLSTACK_PROTO##n,cfunc->ptr); \ f(DLSTACK_ARGS##n(stack)); \ result = Qnil; \ }
Calls the function pointer passing in ary
as values to the
underlying C function. The return value depends on
the ctype.
Source: show
static VALUE rb_dlcfunc_call(VALUE self, VALUE ary) { struct cfunc_data *cfunc; int i; DLSTACK_TYPE stack[DLSTACK_SIZE]; VALUE result = Qnil; rb_secure_update(self); memset(stack, 0, sizeof(DLSTACK_TYPE) * DLSTACK_SIZE); Check_Type(ary, T_ARRAY); TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); if( cfunc->ptr == 0 ){ rb_raise(rb_eDLError, "can't call null-function"); return Qnil; } for( i = 0; i < RARRAY_LEN(ary); i++ ){ VALUE arg; if( i >= DLSTACK_SIZE ){ rb_raise(rb_eDLError, "too many arguments (stack overflow)"); } arg = rb_to_int(RARRAY_PTR(ary)[i]); rb_check_safe_obj(arg); if (FIXNUM_P(arg)) { stack[i] = (DLSTACK_TYPE)FIX2LONG(arg); } else if (RB_TYPE_P(arg, T_BIGNUM)) { #if SIZEOF_VOIDP == SIZEOF_LONG stack[i] = (DLSTACK_TYPE)rb_big2ulong_pack(arg); #else stack[i] = (DLSTACK_TYPE)rb_big2ull(arg); #endif } else { Check_Type(arg, T_FIXNUM); } } /* calltype == CFUNC_CDECL */ if( cfunc->calltype == CFUNC_CDECL #ifndef FUNC_STDCALL || cfunc->calltype == CFUNC_STDCALL #endif ){ switch( cfunc->type ){ case DLTYPE_VOID: #define CASE(n) case n: { \ DECL_FUNC_CDECL(f,void,DLSTACK_PROTO##n,cfunc->ptr); \ f(DLSTACK_ARGS##n(stack)); \ result = Qnil; \ }
Get the call type of this function.
Source: show
static VALUE rb_dlcfunc_calltype(VALUE self) { struct cfunc_data *cfunc; TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); return ID2SYM(cfunc->calltype); }
Set the call type for this function.
Source: show
static VALUE rb_dlcfunc_set_calltype(VALUE self, VALUE sym) { struct cfunc_data *cfunc; TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); cfunc->calltype = SYM2ID(sym); return sym; }
Get the C function return value type. See DL for a list of constants corresponding to this method's return value.
Source: show
static VALUE rb_dlcfunc_ctype(VALUE self) { struct cfunc_data *cfunc; TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); return INT2NUM(cfunc->type); }
Source: show
static VALUE rb_dlcfunc_set_ctype(VALUE self, VALUE ctype) { struct cfunc_data *cfunc; TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); cfunc->type = NUM2INT(ctype); return ctype; }
Returns a string formatted with an easily readable representation of the internal state of the DL::CFunc
Source: show
static VALUE rb_dlcfunc_inspect(VALUE self) { VALUE val; struct cfunc_data *cfunc; TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); val = rb_sprintf("#<DL::CFunc:%p ptr=%p type=%d name='%s'>", cfunc, cfunc->ptr, cfunc->type, cfunc->name ? cfunc->name : ""); OBJ_TAINT(val); return val; }
Get the name of this function
Source: show
static VALUE rb_dlcfunc_name(VALUE self) { struct cfunc_data *cfunc; TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); return cfunc->name ? rb_tainted_str_new2(cfunc->name) : Qnil; }
Get the underlying function pointer as a DL::CPtr object.
Source: show
static VALUE rb_dlcfunc_ptr(VALUE self) { struct cfunc_data *cfunc; TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); return PTR2NUM(cfunc->ptr); }
Source: show
static VALUE rb_dlcfunc_set_ptr(VALUE self, VALUE addr) { struct cfunc_data *cfunc; TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); cfunc->ptr = NUM2PTR(addr); return Qnil; }
Returns the memory location of this function pointer as an integer.
Source: show
static VALUE rb_dlcfunc_to_i(VALUE self) { struct cfunc_data *cfunc; TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); return PTR2NUM(cfunc->ptr); }
Returns a string formatted with an easily readable representation of the internal state of the DL::CFunc
Source: show
static VALUE rb_dlcfunc_inspect(VALUE self) { VALUE val; struct cfunc_data *cfunc; TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, cfunc); val = rb_sprintf("#<DL::CFunc:%p ptr=%p type=%d name='%s'>", cfunc, cfunc->ptr, cfunc->type, cfunc->name ? cfunc->name : ""); OBJ_TAINT(val); return val; }