Beispiel #1
0
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

}
Beispiel #2
0
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
}