func Prepare(fun *Function, nargs uint) (*Callable, int) { var cif C.ffi_cif var typp *C.ffi_type ffi_type_void := ffi_type_for(TYPE_VOID, nil) // recover from panic here defer func() { if x := recover(); x != nil { println("panicking with value", x) } println("function returns normally") // executes only when hideErrors==true }() call := &Callable{} println("cif size: ", unsafe.Sizeof(cif)) call.cifmem = Allocate(unsafe.Sizeof(cif) + 100) call.argimem = Allocate(unsafe.Sizeof(typp) * 10) call.cif = &call.cifs // (*C.ffi_cif)(call.cifmem.Ptr()) // fmt.Println("cif ABI, nargs:", int(call.cif.abi), int(call.cif.nargs)) call.cif.abi = C.FFI_DEFAULT_ABI call.cif.nargs = C.uint(nargs) call.fun = fun call.cif.rtype = &ffi_type_void //stat := 777 println("cif address:", (unsafe.Pointer)(call.cif)) println("void type address:", (unsafe.Pointer)(&ffi_type_void)) println("cgo void type address:", (unsafe.Pointer)(&C.ffi_type_void)) stat := C.ffi_prep_cif(call.cif, C.FFI_DEFAULT_ABI, C.uint(nargs), &ffi_type_void, nil) /*&C.ffi_type_void, (**C.ffi_type)(call.argimem.ptr))*/ return call, int(stat) }
func create_func(f interface{}) *CFn { cfn := new(CFn) closure := C.ffi_closure_alloc( C.size_t(unsafe.Sizeof(C.ffi_closure{})), &(cfn.fn_ptr)) if closure == nil { return nil } cfn.closure = closure runtime.SetFinalizer(cfn, free_cfn) fn_data := new(FuncData) fn_data.fn = reflect.ValueOf(f) fn_data.fn_type = fn_data.fn.Type() cfn.fn_data = fn_data numIn := fn_data.NumIn() args := get_args_define(fn_data.InTypes(), numIn) var ret_type *C.ffi_type numOut := fn_data.NumOut() if numOut == 1 { ret_type = ffi_type(fn_data.OutTypes()[0]) // fmt.Println((fn_data.OutTypes()[0]).Kind()) } else { // TODO: please handle numOut > 1 ret_type = &C.ffi_type_void } if C.ffi_prep_cif(&(fn_data.cif), C.FFI_DEFAULT_ABI, C.uint(numIn), ret_type, args) != C.FFI_OK { return nil } if C.ffi_prep_closure_loc( (*C.ffi_closure)(closure), &(fn_data.cif), (*[0]byte)(C.binding), unsafe.Pointer(fn_data), cfn.fn_ptr) != C.FFI_OK { return nil } return cfn }
func NewCIF(abi ABI, rtype Type, atypes ...Type) (CIF, error) { var cif C.ffi_cif atypes_ptr := (**C.ffi_type)(unsafe.Pointer(&atypes[0])) status := C.ffi_prep_cif(&cif, C.ffi_abi(abi), C.uint(len(atypes)), rtype, atypes_ptr) if status == C.FFI_OK { return CIF(cif), nil } return CIF{}, ffi_error(status) }
// NewCif creates a new ffi call interface object func NewCif(abi Abi, rtype Type, args []Type) (*Cif, error) { cif := &Cif{} c_nargs := C.uint(len(args)) var c_args **C.ffi_type = nil if len(args) > 0 { var cargs = make([]*C.ffi_type, len(args)) for i, _ := range args { cargs[i] = args[i].cptr() } c_args = &cargs[0] } sc := C.ffi_prep_cif(&cif.c, C.ffi_abi(abi), c_nargs, rtype.cptr(), c_args) if sc != C.FFI_OK { return nil, fmt.Errorf("error while preparing cif (%s)", Status(sc)) } cif.rtype = rtype cif.args = args return cif, nil }
func Prepare(ret Type, args ...Type) (cif Interface) { cif.ffi_ret = ret.ffi_type cif.ret = ret cif.args = args argc := len(args) if argc != 0 { va := make([]*C.ffi_type, argc) for i, a := range args { va[i] = a.ffi_type } cif.ffi_args = &va[0] } if status := Status(C.ffi_prep_cif(&cif.ffi_cif, C.FFI_DEFAULT_ABI, C.uint(argc), cif.ffi_ret, cif.ffi_args)); status != OK { panic(status) } return }