On this page
class Fiddle::Function
Description
A representation of a C function
Examples
'strcpy'
@libc = Fiddle.dlopen "/lib/libc.so.6"
#=> #<Fiddle::Handle:0x00000001d7a8d8>
f = Fiddle::Function.new(
@libc['strcpy'],
[Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP],
Fiddle::TYPE_VOIDP)
#=> #<Fiddle::Function:0x00000001d8ee00>
buff = "000"
#=> "000"
str = f.call(buff, "123")
#=> #<Fiddle::Pointer:0x00000001d0c380 ptr=0x000000018a21b8 size=0 free=0x00000000000000>
str.to_s
=> "123"
ABI check
@libc = Fiddle.dlopen "/lib/libc.so.6"
#=> #<Fiddle::Handle:0x00000001d7a8d8>
f = Fiddle::Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP)
#=> #<Fiddle::Function:0x00000001d8ee00>
f.abi == Fiddle::Function::DEFAULT
#=> true
Constants
Attributes
abi[R]
The ABI of the Function.
name[R]
The name of this function
ptr[R]
The address of this function
Public Class Methods
new(ptr, args, ret_type, abi = DEFAULT) Show source
static VALUE
initialize(int argc, VALUE argv[], VALUE self)
{
ffi_cif * cif;
ffi_type **arg_types;
ffi_status result;
VALUE ptr, args, ret_type, abi, kwds;
int i;
rb_scan_args(argc, argv, "31:", &ptr, &args, &ret_type, &abi, &kwds);
if(NIL_P(abi)) abi = INT2NUM(FFI_DEFAULT_ABI);
Check_Type(args, T_ARRAY);
Check_Max_Args("args", RARRAY_LENINT(args));
rb_iv_set(self, "@ptr", ptr);
rb_iv_set(self, "@args", args);
rb_iv_set(self, "@return_type", ret_type);
rb_iv_set(self, "@abi", abi);
if (!NIL_P(kwds)) rb_hash_foreach(kwds, parse_keyword_arg_i, self);
TypedData_Get_Struct(self, ffi_cif, &function_data_type, cif);
arg_types = xcalloc(RARRAY_LEN(args) + 1, sizeof(ffi_type *));
for (i = 0; i < RARRAY_LEN(args); i++) {
int type = NUM2INT(RARRAY_PTR(args)[i]);
arg_types[i] = INT2FFI_TYPE(type);
}
arg_types[RARRAY_LEN(args)] = NULL;
result = ffi_prep_cif (
cif,
NUM2INT(abi),
RARRAY_LENINT(args),
INT2FFI_TYPE(NUM2INT(ret_type)),
arg_types);
if (result)
rb_raise(rb_eRuntimeError, "error creating CIF %d", result);
return self;
}
Constructs a Function object.
ptr
is a referenced function, of a Fiddle::Handleargs
is an Array of arguments, passed to theptr
functionret_type
is the return type of the functionabi
is the ABI of the function
Public Instance Methods
static VALUE
function_call(int argc, VALUE argv[], VALUE self)
{
ffi_cif * cif;
fiddle_generic retval;
fiddle_generic *generic_args;
void **values;
VALUE cfunc, types, cPointer;
int i;
VALUE alloc_buffer = 0;
cfunc = rb_iv_get(self, "@ptr");
types = rb_iv_get(self, "@args");
cPointer = rb_const_get(mFiddle, rb_intern("Pointer"));
Check_Max_Args("number of arguments", argc);
if(argc != RARRAY_LENINT(types)) {
rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
argc, RARRAY_LENINT(types));
}
TypedData_Get_Struct(self, ffi_cif, &function_data_type, cif);
if (rb_safe_level() >= 1) {
for (i = 0; i < argc; i++) {
VALUE src = argv[i];
if (OBJ_TAINTED(src)) {
rb_raise(rb_eSecurityError, "tainted parameter not allowed");
}
}
}
generic_args = ALLOCV(alloc_buffer,
(size_t)(argc + 1) * sizeof(void *) + (size_t)argc * sizeof(fiddle_generic));
values = (void **)((char *)generic_args + (size_t)argc * sizeof(fiddle_generic));
for (i = 0; i < argc; i++) {
VALUE type = RARRAY_PTR(types)[i];
VALUE src = argv[i];
if(NUM2INT(type) == TYPE_VOIDP) {
if(NIL_P(src)) {
src = INT2FIX(0);
} else if(cPointer != CLASS_OF(src)) {
src = rb_funcall(cPointer, rb_intern("[]"), 1, src);
}
src = rb_Integer(src);
}
VALUE2GENERIC(NUM2INT(type), src, &generic_args[i]);
values[i] = (void *)&generic_args[i];
}
values[argc] = NULL;
ffi_call(cif, NUM2PTR(rb_Integer(cfunc)), &retval, values);
rb_funcall(mFiddle, rb_intern("last_error="), 1, INT2NUM(errno));
#if defined(_WIN32)
rb_funcall(mFiddle, rb_intern("win32_last_error="), 1, INT2NUM(errno));
#endif
ALLOCV_END(alloc_buffer);
return GENERIC2VALUE(rb_iv_get(self, "@return_type"), retval);
}
Calls the constructed Function, with args
For an example see Fiddle::Function
# File ext/fiddle/lib/fiddle/function.rb, line 13
def to_i
ptr.to_i
end
The integer memory location of this function
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.