@param [Type, Symbol] return_type return type for the function @param [Array<Type, Symbol>] param_types array of parameters types @param [Hash] options see {FFI::FunctionType} for available options @return [self] A new Function instance.
Define a function from a Proc or a block.
@overload initialize(return_type, param_types, options = {}) { |i| ... }
@yieldparam i parameters for the function
@overload initialize(return_type, param_types, proc, options = {})
@param [Proc] proc
static VALUE function_initialize(int argc, VALUE* argv, VALUE self) { VALUE rbReturnType = Qnil, rbParamTypes = Qnil, rbProc = Qnil, rbOptions = Qnil; VALUE rbFunctionInfo = Qnil; VALUE infoArgv[3]; int nargs; nargs = rb_scan_args(argc, argv, "22", &rbReturnType, &rbParamTypes, &rbProc, &rbOptions); /* * Callback with block, * e.g. Function.new(:int, [ :int ]) { |i| blah } * or Function.new(:int, [ :int ], { :convention => :stdcall }) { |i| blah } */ if (rb_block_given_p()) { if (nargs > 3) { rb_raise(rb_eArgError, "cannot create function with both proc/address and block"); } rbOptions = rbProc; rbProc = rb_block_proc(); } else { /* Callback with proc, or Function with address * e.g. Function.new(:int, [ :int ], Proc.new { |i| }) * Function.new(:int, [ :int ], Proc.new { |i| }, { :convention => :stdcall }) * Function.new(:int, [ :int ], addr) * Function.new(:int, [ :int ], addr, { :convention => :stdcall }) */ } infoArgv[0] = rbReturnType; infoArgv[1] = rbParamTypes; infoArgv[2] = rbOptions; rbFunctionInfo = rb_class_new_instance(rbOptions != Qnil ? 3 : 2, infoArgv, rbffi_FunctionTypeClass); function_init(self, rbFunctionInfo, rbProc); return self; }
static VALUE function_attach(VALUE self, VALUE module, VALUE name) { Function* fn; char var[1024]; Data_Get_Struct(self, Function, fn); if (fn->info->parameterCount == -1) { rb_raise(rb_eRuntimeError, "cannot attach variadic functions"); return Qnil; } if (!rb_obj_is_kind_of(module, rb_cModule)) { rb_raise(rb_eRuntimeError, "trying to attach function to non-module"); return Qnil; } if (fn->methodHandle == NULL) { fn->methodHandle = rbffi_MethodHandle_Alloc(fn->info, fn->base.memory.address); } /* * Stash the Function in a module variable so it does not get garbage collected */ snprintf(var, sizeof(var), "@@%s", StringValueCStr(name)); rb_cv_set(module, var, self); rb_define_singleton_method(module, StringValueCStr(name), rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1); rb_define_method(module, StringValueCStr(name), rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1); return self; }
static VALUE function_autorelease_p(VALUE self) { Function* fn; Data_Get_Struct(self, Function, fn); return fn->autorelease ? Qtrue : Qfalse; }
static VALUE function_set_autorelease(VALUE self, VALUE autorelease) { Function* fn; Data_Get_Struct(self, Function, fn); fn->autorelease = RTEST(autorelease); return self; }
static VALUE function_autorelease_p(VALUE self) { Function* fn; Data_Get_Struct(self, Function, fn); return fn->autorelease ? Qtrue : Qfalse; }
static VALUE function_call(int argc, VALUE* argv, VALUE self) { Function* fn; Data_Get_Struct(self, Function, fn); return (*fn->info->invoke)(argc, argv, fn->base.memory.address, fn->info); }
static VALUE function_release(VALUE self) { Function* fn; Data_Get_Struct(self, Function, fn); if (fn->closure == NULL) { rb_raise(rb_eRuntimeError, "cannot free function which was not allocated"); } rbffi_Closure_Free(fn->closure); fn->closure = NULL; return self; }
Generated with the Darkfish Rdoc Generator 2.