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 constructClosure(fn *function) (err error) { var closure C.ffi_closure var fptr unsafe.Pointer var mptr unsafe.Pointer if mptr, err = C.ffi_closure_alloc(C.size_t(unsafe.Sizeof(closure)), &fptr); mptr == nil { return } if status := Status(C.ffi_prep_closure_loc((*C.ffi_closure)(mptr), &fn.Interface.ffi_cif, C.closure(C.GoClosureCallback), unsafe.Pointer(fn), fptr)); status != OK { C.ffi_closure_free(mptr) err = status return } fn.fptr = fptr fn.mptr = mptr return nil }