static VALUE initialize(int argc, VALUE argv[], VALUE self) { ffi_cif * cif; ffi_type **arg_types, *rtype; ffi_status result; VALUE ptr, args, ret_type, abi, kwds, ary; int i, len; int nabi; void *cfunc; rb_scan_args(argc, argv, "31:", &ptr, &args, &ret_type, &abi, &kwds); ptr = rb_Integer(ptr); cfunc = NUM2PTR(ptr); PTR2NUM(cfunc); nabi = NIL_P(abi) ? FFI_DEFAULT_ABI : NUM2INT(abi); abi = INT2FIX(nabi); i = NUM2INT(ret_type); rtype = INT2FFI_TYPE(i); ret_type = INT2FIX(i); Check_Type(args, T_ARRAY); len = RARRAY_LENINT(args); Check_Max_Args("args", len); ary = rb_ary_subseq(args, 0, len); for (i = 0; i < RARRAY_LEN(args); i++) { VALUE a = RARRAY_PTR(args)[i]; int type = NUM2INT(a); (void)INT2FFI_TYPE(type); /* raise */ if (INT2FIX(type) != a) rb_ary_store(ary, i, INT2FIX(type)); } OBJ_FREEZE(ary); 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(len + 1, sizeof(ffi_type *)); for (i = 0; i < RARRAY_LEN(args); i++) { int type = NUM2INT(RARRAY_AREF(args, i)); arg_types[i] = INT2FFI_TYPE(type); } arg_types[len] = NULL; result = ffi_prep_cif(cif, nabi, len, rtype, arg_types); if (result) rb_raise(rb_eRuntimeError, "error creating CIF %d", result); return self; }
static VALUE initialize(int rbargc, VALUE argv[], VALUE self) { VALUE ret; VALUE args; VALUE abi; fiddle_closure * cl; ffi_cif * cif; ffi_closure *pcl; ffi_status result; int i, argc; if (2 == rb_scan_args(rbargc, argv, "21", &ret, &args, &abi)) abi = INT2NUM(FFI_DEFAULT_ABI); Check_Type(args, T_ARRAY); argc = RARRAY_LENINT(args); TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, cl); cl->argv = (ffi_type **)xcalloc(argc + 1, sizeof(ffi_type *)); for (i = 0; i < argc; i++) { int type = NUM2INT(RARRAY_PTR(args)[i]); cl->argv[i] = INT2FFI_TYPE(type); } cl->argv[argc] = NULL; rb_iv_set(self, "@ctype", ret); rb_iv_set(self, "@args", args); cif = &cl->cif; pcl = cl->pcl; result = ffi_prep_cif(cif, NUM2INT(abi), argc, INT2FFI_TYPE(NUM2INT(ret)), cl->argv); if (FFI_OK != result) rb_raise(rb_eRuntimeError, "error prepping CIF %d", result); #ifndef DONT_USE_FFI_CLOSURE_ALLOC result = ffi_prep_closure_loc(pcl, cif, callback, (void *)self, cl->code); #else result = ffi_prep_closure(pcl, cif, callback, (void *)self); cl->code = (void *)pcl; mprotect(pcl, sizeof(pcl), PROT_READ | PROT_EXEC); #endif if (FFI_OK != result) rb_raise(rb_eRuntimeError, "error prepping closure %d", result); return self; }
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); 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; }