static void sample_time() { u_char *p; u_char buf[64]; ffi_status status; ffi_cif cif; ffi_type *arg_types[2]; arg_types[0] = &ffi_type_pointer; arg_types[1] = &ffi_type_uint64; // size_t status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_pointer, arg_types); if (status != FFI_OK) { fprintf(stderr, "Error: ffi_prep_cif() failed\n"); return -1; } { void *arg_values[2]; char buf[64]; char *v; time_t tm; char *ret; v = &buf; tm = time(NULL); arg_values[0] = &v; arg_values[1] = &tm; ffi_call(&cif, FFI_FN(ngx_http_cookie_time), &ret, arg_values); printf("ngx_http_cookie_time = %.*s\n", ret - buf, buf); } //p = ngx_http_cookie_time(buf, time(NULL)); #if 0 puts("sample_time --------"); printf("sizeof(time_t) = %d\n", sizeof(time_t)); printf("ngx_time = %ld\n", ngx_time()); printf("ngx_http_cookie_time = %.*s\n", p - buf, buf); #endif return; }
static int router_simple_command(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { RedisModule_AutoMemory(ctx); if (argc < 2) { RedisModule_WrongArity(ctx); return REDISMODULE_OK; } RedisModuleCallReply *reply; size_t len; const char *realCmd = RedisModule_StringPtrLen(argv[1], &len); if (argc == 2) { reply = RedisModule_Call(ctx, realCmd, ""); } else { char *fmt = (char *) malloc(argc-1); memset(fmt, 's', argc-2); fmt[argc-2] = '\0'; ffi_cif cif; ffi_type **ffi_argv = (ffi_type **)malloc(sizeof(ffi_type *) * (argc + 1)); void *result; int i; for (i = 0; i < argc+1; i++) { ffi_argv[i] = &ffi_type_pointer; } void **values = (void **) malloc(sizeof(void *) * (argc + 1)); values[0] = &ctx; values[1] = &realCmd; values[2] = &fmt; for (i = 3; i < argc + 1; i++) { values[i] = &argv[i-1]; } if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, (argc + 1), &ffi_type_pointer, ffi_argv) == FFI_OK) { ffi_call(&cif, FFI_FN(RedisModule_Call), &result, values); } reply = (RedisModuleCallReply *) result; } if (reply == NULL) { const char *err = "command error"; RedisModule_ReplyWithError(ctx, err); } else { RedisModule_ReplyWithCallReply(ctx, reply); } return REDISMODULE_OK; }
/** * g_callable_info_prepare_closure: * @callable_info: a callable info from a typelib * @cif: a ffi_cif structure * @callback: the ffi callback * @user_data: data to be passed into the callback * * Prepares a callback for ffi invocation. * * Return value: the ffi_closure or NULL on error. * The return value should be freed by calling g_callable_info_free_closure(). */ ffi_closure * g_callable_info_prepare_closure (GICallableInfo *callable_info, ffi_cif *cif, GIFFIClosureCallback callback, gpointer user_data) { gpointer exec_ptr; GIClosureWrapper *closure; ffi_status status; g_return_val_if_fail (callable_info != NULL, FALSE); g_return_val_if_fail (cif != NULL, FALSE); g_return_val_if_fail (callback != NULL, FALSE); closure = ffi_closure_alloc (sizeof (GIClosureWrapper), &exec_ptr); if (!closure) { g_warning ("could not allocate closure\n"); return NULL; } closure->writable_self = closure; status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, g_callable_info_get_n_args (callable_info), g_callable_info_get_ffi_return_type (callable_info), g_callable_info_get_ffi_arg_types (callable_info)); if (status != FFI_OK) { g_warning ("ffi_prep_cif failed: %d\n", status); ffi_closure_free (closure); return NULL; } status = ffi_prep_closure_loc (&closure->ffi_closure, cif, callback, user_data, exec_ptr); if (status != FFI_OK) { g_warning ("ffi_prep_closure failed: %d\n", status); ffi_closure_free (closure); return NULL; } /* Return exec_ptr, which points to the same underlying memory as * closure, but via an executable-non-writable mapping. */ return exec_ptr; }
int main() { ffi_cif cif; ffi_type my_struct_type; ffi_type *my_struct_eles[4] = { &ffi_type_sint, &ffi_type_pointer, &ffi_type_sint, NULL }; ffi_type *args[1]; void *values[1]; my_struct ms = { .i = 1, .j = 2, .str = "asdf" }; my_struct_type.size = my_struct_type.alignment = 0; my_struct_type.elements = my_struct_eles; args[0] = &my_struct_type; values[0] = &ms; printf("\033[31;1mBefore Init\033[0m\n"); printf("my_struct_type:\n"); print_type(args[0]); printf("ffi_type_void:\n"); print_type(&ffi_type_void); if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, args) == FFI_OK) { printf("\033[31;1mAfter Prep CIF\033[0m\n"); print_cif(&cif); printf("\033[32;1mCall First Time\033[0m\n"); ffi_call(&cif, (fpointer)print_my_struct, NULL, values); printf("\033[31;1mAfter First Call\033[0m\n"); print_cif(&cif); ms.str = "Hello"; printf("\033[32;1mCall Second Time\033[0m\n"); ffi_call(&cif, (fpointer)print_my_struct, NULL, values); printf("\033[31;1mAfter Second Call\033[0m\n"); print_cif(&cif); } return 0; }
int main (void) { ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; ffi_type ts9_type; ffi_type *ts9_type_elements[3]; test_structure_9 ts9_arg; /* This is a hack to get a properly aligned result buffer */ test_structure_9 *ts9_result = (test_structure_9 *) malloc (sizeof(test_structure_9)); ts9_type.size = 0; ts9_type.alignment = 0; ts9_type.type = FFI_TYPE_STRUCT; ts9_type.elements = ts9_type_elements; ts9_type_elements[0] = &ffi_type_float; ts9_type_elements[1] = &ffi_type_sint; ts9_type_elements[2] = NULL; args[0] = &ts9_type; values[0] = &ts9_arg; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts9_type, args) == FFI_OK); ts9_arg.f = 5.55f; ts9_arg.i = 5; printf ("%g\n", ts9_arg.f); printf ("%d\n", ts9_arg.i); ffi_call(&cif, FFI_FN(struct9), ts9_result, values); printf ("%g\n", ts9_result->f); printf ("%d\n", ts9_result->i); CHECK(ts9_result->f == 5.55f + 1); CHECK(ts9_result->i == 5 + 1); free (ts9_result); exit(0); }
int main (void) { ffi_cif cif; static ffi_closure cl; ffi_closure *pcl = &cl; void* args_dbl[5]; ffi_type* cls_struct_fields[2]; ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; struct cls_struct_1_1byte g_dbl = { 12 }; struct cls_struct_1_1byte f_dbl = { 178 }; struct cls_struct_1_1byte res_dbl; cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = NULL; dbl_arg_types[0] = &cls_struct_type; dbl_arg_types[1] = &cls_struct_type; dbl_arg_types[2] = NULL; CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, dbl_arg_types) == FFI_OK); args_dbl[0] = &g_dbl; args_dbl[1] = &f_dbl; args_dbl[2] = NULL; ffi_call(&cif, FFI_FN(cls_struct_1_1byte_fn), &res_dbl, args_dbl); /* { dg-output "12 178: 190" } */ CHECK( res_dbl.a == (g_dbl.a + f_dbl.a)); CHECK(ffi_prep_closure(pcl, &cif, cls_struct_1_1byte_gn, NULL) == FFI_OK); res_dbl = ((cls_struct_1_1byte(*)(cls_struct_1_1byte, cls_struct_1_1byte))(pcl))(g_dbl, f_dbl); /* { dg-output "\n12 178: 190" } */ CHECK( res_dbl.a == (g_dbl.a + f_dbl.a)); exit(0); }
void rbffi_MethodHandle_Init(VALUE module) { defaultClosurePool = rbffi_ClosurePool_New(trampoline_size(), prep_trampoline, NULL); #if defined(CUSTOM_TRAMPOLINE) if (trampoline_offsets(&trampoline_ctx_offset, &trampoline_func_offset) != 0) { rb_raise(rb_eFatal, "Could not locate offsets in trampoline code"); } #else ffi_status ffiStatus = ffi_prep_cif(&mh_cif, FFI_DEFAULT_ABI, 3, &ffi_type_ulong, methodHandleParamTypes); if (ffiStatus != FFI_OK) { rb_raise(rb_eFatal, "ffi_prep_cif failed. status=%#x", ffiStatus); } #endif }
int main (void) { ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; ffi_type ts5_type; ffi_type *ts5_type_elements[3]; test_structure_5 ts5_arg1, ts5_arg2; /* This is a hack to get a properly aligned result buffer */ test_structure_5 *ts5_result = (test_structure_5 *) malloc (sizeof(test_structure_5)); ts5_type.size = 0; ts5_type.alignment = 0; ts5_type.type = FFI_TYPE_STRUCT; ts5_type.elements = ts5_type_elements; ts5_type_elements[0] = &ffi_type_schar; ts5_type_elements[1] = &ffi_type_schar; ts5_type_elements[2] = NULL; args[0] = &ts5_type; args[1] = &ts5_type; values[0] = &ts5_arg1; values[1] = &ts5_arg2; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, &ts5_type, args) == FFI_OK); ts5_arg1.c1 = 2; ts5_arg1.c2 = 6; ts5_arg2.c1 = 5; ts5_arg2.c2 = 3; ffi_call (&cif, FFI_FN(struct5), ts5_result, values); CHECK(ts5_result->c1 == 7); CHECK(ts5_result->c2 == 3); free (ts5_result); exit(0); }
int main (void) { ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; test_structure_2 ts2_arg; ffi_type ts2_type; ffi_type *ts2_type_elements[3]; /* This is a hack to get a properly aligned result buffer */ test_structure_2 *ts2_result = (test_structure_2 *) malloc (sizeof(test_structure_2)); ts2_type.size = 0; ts2_type.alignment = 0; ts2_type.type = FFI_TYPE_STRUCT; ts2_type.elements = ts2_type_elements; ts2_type_elements[0] = &ffi_type_double; ts2_type_elements[1] = &ffi_type_double; ts2_type_elements[2] = NULL; args[0] = &ts2_type; values[0] = &ts2_arg; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts2_type, args) == FFI_OK); ts2_arg.d1 = 5.55; ts2_arg.d2 = 6.66; printf ("%g\n", ts2_arg.d1); printf ("%g\n", ts2_arg.d2); ffi_call(&cif, FFI_FN(struct2), ts2_result, values); printf ("%g\n", ts2_result->d1); printf ("%g\n", ts2_result->d2); CHECK(ts2_result->d1 == 5.55 - 1); CHECK(ts2_result->d2 == 6.66 - 1); free (ts2_result); exit(0); }
static SQInteger sq_lib_bind_func(HSQUIRRELVM v) { void **modbuf; void *mod; void *sym; const SQChar *symname; const char *rettype; sq_getuserdata(v, 1, (void**)&modbuf, NULL); mod = *modbuf; sq_getstring(v, 2, &rettype); sq_getstring(v, 3, &symname); sym = GET_SYM(mod, symname); if (!sym) return sq_throwerror(v, "Cannot find symbol"); int nparam = sq_getsize(v, 4); int size = sizeof(FFIFunc) + sizeof(ffi_type*) * nparam; FFIFunc *ffibuf = (FFIFunc*)sq_newuserdata(v, size); sq_push_delegate_table(v, FFI_LIB_FUNC_TAG); sq_setdelegate(v, -2); // printf("Allocated %d bytes at %p\n", size, ffibuf); ffibuf->func = sym; ffibuf->rettype = *rettype; int i; for (i = 0; i < nparam; i++) { sq_pushinteger(v, i); sq_get(v, 4); ffibuf->params[i] = get_ffi_type(v, -1); if (!ffibuf->params[i]) return SQ_ERROR; sq_poptop(v); } int res = ffi_prep_cif(&ffibuf->cif, FFI_DEFAULT_ABI, nparam, char2ffi_type(*rettype), ffibuf->params); if (res != FFI_OK) return sq_throwerror(v, "Error in ffi_prep_cif"); return 1; }
static int uwsgi_libffi_hook(char *arg) { size_t argc = 0; size_t i; char **argv = uwsgi_split_quoted(arg, strlen(arg), " \t", &argc); if (!argc) goto end; void *func = dlsym(RTLD_DEFAULT, argv[0]); if (!func) goto destroy; ffi_cif cif; ffi_type **args_type = (ffi_type **) uwsgi_malloc(sizeof(ffi_type*) * (argc-1)); void **values = uwsgi_malloc(sizeof(void*) * (argc-1)); for(i=1;i<argc;i++) { size_t skip = 0; args_type[i-1] = uwsgi_libffi_get_type(argv[i], &skip); void *v = uwsgi_libffi_get_value(argv[i] + skip, args_type[i-1]); values[i-1] = v ? v : &argv[i]; uwsgi_log("%d = %s %p\n", i, argv[i], values[i-1]); } if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, argc-1, &ffi_type_sint64, args_type) == FFI_OK) { int64_t rc = 0; uwsgi_log("ready to call\n"); ffi_call(&cif, func, &rc, values); } uwsgi_log("ready to call2\n"); for(i=0;i<(argc-1);i++) { char **ptr = (char **) values[i]; if (*ptr != argv[i+1]) { free(values[i]); } } free(args_type); free(values); destroy: for(i=0;i<argc;i++) { free(argv[i]); } end: free(argv); return -1; }
int main (void) { ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; ffi_arg rint; signed char sc; unsigned char uc; signed short ss; unsigned short us; unsigned long ul; args[0] = &ffi_type_schar; args[1] = &ffi_type_sshort; args[2] = &ffi_type_uchar; args[3] = &ffi_type_ushort; values[0] = ≻ values[1] = &ss; values[2] = &uc; values[3] = &us; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &ffi_type_sint, args) == FFI_OK); us = 0; ul = 0; for (sc = (signed char) -127; sc <= (signed char) 120; sc += 1) for (ss = -30000; ss <= 30000; ss += 10000) for (uc = (unsigned char) 0; uc <= (unsigned char) 200; uc += 20) for (us = 0; us <= 60000; us += 10000) { ul++; ffi_call(&cif, FFI_FN(promotion), &rint, values); CHECK((int)rint == (signed char) sc + (signed short) ss + (unsigned char) uc + (unsigned short) us); } printf("%lu promotion tests run\n", ul); exit(0); }
int main (void) { ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; float f; long double ld; args[0] = &ffi_type_float; values[0] = &f; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_longdouble, args) == FFI_OK); f = 3.14159; #if 1 /* This is ifdef'd out for now. long double support under SunOS/gcc is pretty much non-existent. You'll get the odd bus error in library routines like printf(). */ printf ("%Lf\n", ldblit(f)); #endif ld = 666; ffi_call(&cif, FFI_FN(ldblit), &ld, values); #if 1 /* This is ifdef'd out for now. long double support under SunOS/gcc is pretty much non-existent. You'll get the odd bus error in library routines like printf(). */ printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON); #endif /* These are not always the same!! Check for a reasonable delta */ /*@-realcompare@*/ if (ld - ldblit(f) < LDBL_EPSILON) /*@=realcompare@*/ puts("long double return value tests ok!"); else CHECK(0); exit(0); }
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; }
int main (void) { ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; ffi_type ts1_type; ffi_type *ts1_type_elements[4]; test_structure_1 ts1_arg; /* This is a hack to get a properly aligned result buffer */ test_structure_1 *ts1_result = (test_structure_1 *) malloc (sizeof(test_structure_1)); ts1_type.size = 0; ts1_type.alignment = 0; ts1_type.type = FFI_TYPE_STRUCT; ts1_type.elements = ts1_type_elements; ts1_type_elements[0] = &ffi_type_uchar; ts1_type_elements[1] = &ffi_type_double; ts1_type_elements[2] = &ffi_type_uint; ts1_type_elements[3] = NULL; args[0] = &ts1_type; values[0] = &ts1_arg; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 1, &ts1_type, args) == FFI_OK); ts1_arg.uc = '\x01'; ts1_arg.d = 3.14159; ts1_arg.ui = 555; ffi_call(&cif, FFI_FN(struct1), ts1_result, values); CHECK(ts1_result->ui == 556); CHECK(ts1_result->d == 3.14159 - 1); free (ts1_result); exit(0); }
static knh_xblock_t *knh_generateWrapper(CTX ctx, void *callee, int argc, knh_ffiparam_t *argv) { knh_xblock_t *blk = get_unused_xblock(ctx); knh_xblock_t *function = blk->block; size_t fidx = 0; int i = 0; knh_ffiparam_t *t; // local ffiarguments; ffi_cif *cif = (ffi_cif*)KNH_MALLOC(ctx, sizeof(ffi_cif)); ffi_type **args = (ffi_type**)KNH_MALLOC(ctx, sizeof(ffi_type) * argc); void *values[1]; for (i = 0; i < argc; i++) { t = &argv[i]; if (t->sfpidx != -1) { // it means arguments switch(t->type) { case CLASS_Tvoid: // do nothing break; case CLASS_Int: args[i] = &ffi_type_uint64; break; case CLASS_Float: args[i] = &ffi_type_double; break; default: args[i] = &ffi_type_pointer; break; } } } if (ffi_prep_cif(cif, FFI_DEFAULT_ABI, argc, &ffi_type_void, args) == FFI_OK) { fprintf(stderr, "OKAY!\n"); } else { fprintf(stderr, "this is not okay!\n"); } }
static void call_init(mrb_state *mrb, void (*fn)(void), void *ctx) { ffi_cif cif; ffi_type *args[1]; void *values[1]; int rc; void *c; args[0] = &ffi_type_pointer; if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_uint, args) != FFI_OK) { mrb_raise(mrb, E_RUNTIME_ERROR, "cannot execute function"); } c = ctx; values[0] = &c; ffi_call(&cif, fn, &rc, values); }
int main (void) { ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; ffi_type ts4_type; ffi_type *ts4_type_elements[4]; test_structure_4 ts4_arg; /* This is a hack to get a properly aligned result buffer */ test_structure_4 *ts4_result = (test_structure_4 *) malloc (sizeof(test_structure_4)); ts4_type.size = 0; ts4_type.alignment = 0; ts4_type.type = FFI_TYPE_STRUCT; ts4_type.elements = ts4_type_elements; ts4_type_elements[0] = &ffi_type_uint; ts4_type_elements[1] = &ffi_type_uint; ts4_type_elements[2] = &ffi_type_uint; ts4_type_elements[3] = NULL; args[0] = &ts4_type; values[0] = &ts4_arg; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts4_type, args) == FFI_OK); ts4_arg.ui1 = 2; ts4_arg.ui2 = 3; ts4_arg.ui3 = 4; ffi_call (&cif, FFI_FN(struct4), ts4_result, values); CHECK(ts4_result->ui3 == 2U * 3U * 4U); free (ts4_result); exit(0); }
SEXP R_ffi_prep_cif(SEXP r_abi, SEXP r_retType, SEXP r_argTypes, SEXP r_obj) { ffi_cif *cif; ffi_type *retType; ffi_type **argTypes = NULL; int nargs = Rf_length(r_argTypes), i; ffi_status status; SEXP pointerInputs, ans; cif = calloc(1, sizeof(ffi_cif)); if(!cif) { PROBLEM "can't allocate ffi_cif structure" ERROR; } PROTECT(pointerInputs = NEW_LOGICAL(nargs)); if(nargs > 0) { argTypes = (ffi_type **) malloc(sizeof(ffi_type *) * nargs); for(i = 0; i < nargs; i++) { argTypes[i] = GET_FFI_TYPE_REF(VECTOR_ELT(r_argTypes, i)); LOGICAL(pointerInputs)[i] = (argTypes[i] == &ffi_type_pointer); } } retType = GET_FFI_TYPE_REF(r_retType); status = ffi_prep_cif(cif, INTEGER(r_abi)[0], nargs, retType, argTypes); if(status != FFI_OK) { free(cif); if(argTypes) free(argTypes); PROBLEM "failed to prepare ffi call" ERROR; } PROTECT(ans = makeCIFSEXP(cif, argTypes, retType, r_obj, pointerInputs)); UNPROTECT(2); return(ans); }
static SeedValue seed_ffi_function_call (SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException *exception) { GArgument rvalue; GArgument *gargs; ffi_type *rtype; ffi_type **atypes; gpointer *args; int i; ffi_cif cif; seed_ffi_function_priv *priv = seed_object_get_private (function); if (argument_count != priv->n_args) { seed_make_exception (ctx, exception, "ArgumentError", "%s expected %d arguments got %zd", priv->name, priv->n_args, argument_count); return seed_make_null (ctx); } atypes = g_alloca (sizeof (ffi_type *) * (argument_count)); args = g_alloca (sizeof (gpointer) * (argument_count)); gargs = g_alloca (sizeof (GArgument) * (argument_count)); for (i = 0; i < argument_count; i++) { atypes[i] = gtype_to_ffi_type (ctx, arguments[i], priv->args[i], &(gargs[i]), &args[i],exception); } rtype = return_type_to_ffi_type (priv->ret_val); if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, argument_count, rtype, atypes) != FFI_OK) g_assert_not_reached(); ffi_call (&cif, priv->symbol, &rvalue, args); return value_from_ffi_type (ctx, priv->ret_val, &rvalue, exception); }
SEXP FFI_makeCIF(SEXP retval,SEXP types) { ffi_cif *cif = (ffi_cif*)malloc(sizeof(ffi_cif)+length(types)*sizeof(ffi_type*)); ffi_type **typespec = (ffi_type**)( ((char*)cif)+sizeof(ffi_cif)); int i; SEXP p,ret; PROTECT(p = allocVector(VECSXP,2)); SET_VECTOR_ELT(p,0,retval); SET_VECTOR_ELT(p,1,types); PROTECT(ret = R_MakeExternalPtr(cif,R_NilValue,p)); for(i=0;i<length(types);i++) { SEXP type = VECTOR_ELT(types,i); if(TYPEOF(type) != EXTPTRSXP && R_ExternalPtrTag(type) != FFI_TypeTag) error("Not a type description?"); typespec[i] = R_ExternalPtrAddr(VECTOR_ELT(types,i)); } ffi_prep_cif(R_ExternalPtrAddr(ret),FFI_DEFAULT_ABI,length(types), R_ExternalPtrAddr(retval),typespec); UNPROTECT(2); return ret; }
int main (void) { ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; ffi_arg rint; char *s; int v1; float v2; args[2] = &ffi_type_sint; args[1] = &ffi_type_pointer; args[0] = &ffi_type_float; values[2] = (void*) &v1; values[1] = (void*) &s; values[0] = (void*) &v2; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, ABI_NUM, 3, &ffi_type_sint, args) == FFI_OK); s = "a"; v1 = 1; v2 = 0.0; ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 2); s = "1234567"; v2 = -1.0; v1 = -2; ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 4); s = "1234567890123456789012345"; v2 = 1.0; v1 = 2; ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 28); exit(0); }
int main (void) { ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; double dbl, rdbl; args[0] = &ffi_type_double; values[0] = &dbl; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_double, args) == FFI_OK); for (dbl = -127.3; dbl < 127; dbl++) { ffi_call(&cif, FFI_FN(return_dbl), &rdbl, values); printf ("%f vs %f\n", rdbl, return_dbl(dbl)); CHECK(rdbl == 2 * dbl); } exit(0); }
int main (void) { ffi_cif cif; static ffi_closure cl; ffi_closure *pcl = &cl; ffi_type * cl_arg_types[2]; cl_arg_types[0] = &ffi_type_ushort; cl_arg_types[1] = NULL; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_ushort, cl_arg_types) == FFI_OK); CHECK(ffi_prep_closure(pcl, &cif, cls_ret_ushort_fn, NULL) == FFI_OK); (*((cls_ret_ushort)pcl))(65535); /* { dg-output "65535: 65535" } */ exit(0); }
int main (void) { ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; int compare_value; ffi_type ts3_type; ffi_type *ts3_type_elements[2]; test_structure_3 ts3_arg; test_structure_3 *ts3_result = (test_structure_3 *) malloc (sizeof(test_structure_3)); ts3_type.size = 0; ts3_type.alignment = 0; ts3_type.type = FFI_TYPE_STRUCT; ts3_type.elements = ts3_type_elements; ts3_type_elements[0] = &ffi_type_sint; ts3_type_elements[1] = NULL; args[0] = &ts3_type; values[0] = &ts3_arg; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts3_type, args) == FFI_OK); ts3_arg.si = -123; compare_value = ts3_arg.si; ffi_call(&cif, FFI_FN(struct3), ts3_result, values); printf ("%d %d\n", ts3_result->si, -(compare_value*2)); CHECK(ts3_result->si == -(compare_value*2)); free (ts3_result); exit(0); }
static int alien_callback_new(lua_State *L) { int fn_ref; alien_Callback *ac; ffi_closure **ud; ffi_status status; ffi_abi abi; luaL_checktype(L, 1, LUA_TFUNCTION); ac = (alien_Callback *)malloc(sizeof(alien_Callback)); ud = (ffi_closure **)lua_newuserdata(L, sizeof(ffi_closure**)); if(ac != NULL && ud != NULL) { int j; *ud = malloc_closure(); if(*ud == NULL) { free(ac); luaL_error(L, "alien: cannot allocate callback"); } ac->L = L; ac->ret_type = AT_VOID; ac->ffi_ret_type = &ffi_type_void; abi = FFI_DEFAULT_ABI; ac->nparams = 0; ac->params = NULL; ac->ffi_params = NULL; lua_pushvalue(L, 1); ac->fn_ref = lua_ref(L, 1); luaL_getmetatable(L, ALIEN_CALLBACK_META); lua_setmetatable(L, -2); status = ffi_prep_cif(&(ac->cif), abi, ac->nparams, ac->ffi_ret_type, ac->ffi_params); if(status != FFI_OK) luaL_error(L, "alien: cannot create callback"); status = ffi_prep_closure(*ud, &(ac->cif), &alien_callback_call, ac); ac->fn = *ud; ac->lib = NULL; ac->name = NULL; if(status != FFI_OK) luaL_error(L, "alien: cannot create callback"); return 1; } else { if(ac) free(ac); luaL_error(L, "alien: cannot allocate callback"); } return 0; }
int main (void) { ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; float fl, rfl; args[0] = &ffi_type_float; values[0] = &fl; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_float, args) == FFI_OK); for (fl = -127.0; fl < 127; fl++) { ffi_call(&cif, FFI_FN(return_fl), &rfl, values); printf ("%f vs %f\n", rfl, return_fl(fl)); CHECK(rfl == 2 * fl); } exit(0); }
static cell_t CCall(cell_t count, cell_t func) { int res; int i; ffi_cif cif; ffi_type **args = (ffi_type**)malloc(count * sizeof(*args)); void **values = (void**)malloc(count * sizeof(void*)); /* Example with custom structure! * Forth has structures too, so it's a good idea to map them somehow. * * struct bar arg3; * ffi_type bar_type; * ffi_type *bar_type_elements[count]; * bar_type.size = bar_type.alignment = 0; * bar_type.elements = bar_type_elements; * bar_type.type = FFI_TYPE_STRUCT; * bar_type_elements[0] = &ffi_type_sint; * bar_type_elements[1] = &ffi_type_sint; * bar_type_elements[2] = NULL; * */ char name[255]; ForthStringToC(name, (char *)func, sizeof(name)); void *ptr = dlsym(handler, name); int params[50]; for (i=0; i < count; i++) { params[i] = (int)POP_DATA_STACK; values[i] = ¶ms[i]; args[i] = &ffi_type_sint; } if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, count, &ffi_type_sint, args) == FFI_OK) { ffi_call(&cif, ptr, &res, values); } return res; }
int main (void) { ffi_cif cif; #ifndef USING_MMAP static ffi_closure cl; #endif ffi_closure *pcl; ffi_type * cl_arg_types[17]; int i, res; #ifdef USING_MMAP pcl = allocate_mmap (sizeof(ffi_closure)); #else pcl = &cl; #endif for (i = 0; i < 15; i++) { cl_arg_types[i] = &ffi_type_uint64; } cl_arg_types[15] = &ffi_type_uint; cl_arg_types[16] = NULL; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16, &ffi_type_sint, cl_arg_types) == FFI_OK); CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn0, (void *) 3 /* userdata */) == FFI_OK); res = (*((closure_test_type0)pcl)) (1LL, 2LL, 3LL, 4LL, 127LL, 429LL, 7LL, 8LL, 9LL, 10LL, 11LL, 12LL, 13LL, 19LL, 21LL, 1); /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */ printf("res: %d\n",res); /* { dg-output "\nres: 680" } */ exit(0); }
int main (void) { ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; _Complex int tc_arg; _Complex int tc_result; int tc_int_arg_x; int tc_y; int *tc_ptr_arg_y = &tc_y; args[0] = &ffi_type_complex_sint; args[1] = &ffi_type_sint; args[2] = &ffi_type_pointer; values[0] = &tc_arg; values[1] = &tc_int_arg_x; values[2] = &tc_ptr_arg_y; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &ffi_type_complex_sint, args) == FFI_OK); tc_arg = 1 + 7 * I; tc_int_arg_x = 1234; tc_y = 9876; ffi_call(&cif, FFI_FN(f_complex), &tc_result, values); printf ("%d,%di %d,%di, x %d 1234, y %d 11110\n", (int)tc_result, (int)(tc_result * -I), 2, 8, tc_int_arg_x, tc_y); /* dg-output "-2,8i 2,8i, x 1234 1234, y 11110 11110" */ CHECK (creal (tc_result) == -2); CHECK (cimag (tc_result) == 8); CHECK (tc_int_arg_x == 1234); CHECK (*tc_ptr_arg_y == 11110); exit(0); }