Beispiel #1
0
func Call(cif CIF, fn uintptr, rval uintptr, args ...uintptr) {
	C.ffi_call(
		(*C.ffi_cif)(&cif),
		(*[0]byte)(unsafe.Pointer(fn)),
		unsafe.Pointer(rval),
		(*unsafe.Pointer)(unsafe.Pointer(&args[0])),
	)
}
Beispiel #2
0
func (cif Interface) Call(fptr unsafe.Pointer, ret unsafe.Pointer, args ...unsafe.Pointer) (err error) {
	var va *unsafe.Pointer

	if len(args) != 0 {
		va = &args[0]
	}

	_, err = C.ffi_call(&cif.ffi_cif, C.function(fptr), ret, va)
	return
}
Beispiel #3
0
func (call *Callable) Call() {
	C.ffi_call(call.cif, ffi_func(call.fun.ptr), nil, nil)
}
Beispiel #4
0
// Call invokes the cif with the provided function pointer and arguments
func (cif *Cif) Call(fct FctPtr, args ...interface{}) (reflect.Value, error) {
	nargs := len(args)
	if nargs != int(cif.c.nargs) {
		return reflect.New(reflect.TypeOf(0)), fmt.Errorf("ffi: invalid number of arguments. expected '%d', got '%s'.",
			int(cif.c.nargs), nargs)
	}
	var c_args *unsafe.Pointer = nil
	if nargs > 0 {
		cargs := make([]unsafe.Pointer, nargs)
		for i, _ := range args {
			var carg unsafe.Pointer
			//fmt.Printf("[%d]: (%v)\n", i, args[i])
			t := reflect.TypeOf(args[i])
			rv := reflect.ValueOf(args[i])
			switch t.Kind() {
			case reflect.String:
				cstr := C.CString(args[i].(string))
				defer C.free(unsafe.Pointer(cstr))
				carg = unsafe.Pointer(&cstr)
			case reflect.Ptr:
				carg = unsafe.Pointer(rv.Elem().UnsafeAddr())
			case reflect.Float32:
				vv := args[i].(float32)
				rv = reflect.ValueOf(&vv)
				carg = unsafe.Pointer(rv.Elem().UnsafeAddr())
			case reflect.Float64:
				vv := args[i].(float64)
				rv = reflect.ValueOf(&vv)
				carg = unsafe.Pointer(rv.Elem().UnsafeAddr())
			case reflect.Int:
				vv := args[i].(int)
				rv = reflect.ValueOf(&vv)
				carg = unsafe.Pointer(rv.Elem().UnsafeAddr())
			case reflect.Int8:
				vv := args[i].(int8)
				rv = reflect.ValueOf(&vv)
				carg = unsafe.Pointer(rv.Elem().UnsafeAddr())
			case reflect.Int16:
				vv := args[i].(int16)
				rv = reflect.ValueOf(&vv)
				carg = unsafe.Pointer(rv.Elem().UnsafeAddr())
			case reflect.Int32:
				vv := args[i].(int32)
				rv = reflect.ValueOf(&vv)
				carg = unsafe.Pointer(rv.Elem().UnsafeAddr())
			case reflect.Int64:
				vv := args[i].(int64)
				rv = reflect.ValueOf(&vv)
				carg = unsafe.Pointer(rv.Elem().UnsafeAddr())
			case reflect.Uint:
				vv := args[i].(uint)
				rv = reflect.ValueOf(&vv)
				carg = unsafe.Pointer(rv.Elem().UnsafeAddr())
			case reflect.Uint8:
				vv := args[i].(uint8)
				rv = reflect.ValueOf(&vv)
				carg = unsafe.Pointer(rv.Elem().UnsafeAddr())
			case reflect.Uint16:
				vv := args[i].(uint16)
				rv = reflect.ValueOf(&vv)
				carg = unsafe.Pointer(rv.Elem().UnsafeAddr())
			case reflect.Uint32:
				vv := args[i].(uint32)
				rv = reflect.ValueOf(&vv)
				carg = unsafe.Pointer(rv.Elem().UnsafeAddr())
			case reflect.Uint64:
				vv := args[i].(uint64)
				rv = reflect.ValueOf(&vv)
				carg = unsafe.Pointer(rv.Elem().UnsafeAddr())
			}
			cargs[i] = carg
		}
		c_args = &cargs[0]
	}
	out := reflect.New(rtype_from_ffi(cif.rtype.cptr()))
	var c_out unsafe.Pointer = unsafe.Pointer(out.Elem().UnsafeAddr())
	//println("...ffi_call...")
	C.ffi_call(&cif.c, fct.c, c_out, c_args)
	//fmt.Printf("...ffi_call...[done] [%v]\n",out.Elem())
	return out.Elem(), nil
}