func newTypeFromFactoryFunction(function interface{}, factoryType reflect.Type, parameters []interface{}) TypeFactory { if factoryType.NumOut() != 1 { return newInvalidType(fmt.Errorf("invalid number of return parameters: %d", factoryType.NumOut())) } kindOfGeneratedType := factoryType.Out(0).Kind() if kindOfGeneratedType != reflect.Interface && kindOfGeneratedType != reflect.Ptr { return newInvalidType(fmt.Errorf("return parameter is no interface or pointer but a %v", kindOfGeneratedType)) } if factoryType.IsVariadic() { if factoryType.NumIn() > len(parameters) { return newInvalidType(fmt.Errorf("invalid number of input parameters for variadic function: got %d but expected at least %d", len(parameters), factoryType.NumIn())) } } else { if factoryType.NumIn() != len(parameters) { return newInvalidType(fmt.Errorf("invalid number of input parameters: got %d but expected %d", len(parameters), factoryType.NumIn())) } } t := &typeFactory{ factory: reflect.ValueOf(function), factoryType: factoryType, } var err error t.factoryArguments, err = buildFactoryCallArguments(factoryType, parameters) if err != nil { return newInvalidType(err) } return t }
// t's Kind must be a reflect.Func. func funcArgsFromType(t reflect.Type) (in []*Parameter, variadic *Parameter, out []*Parameter, err error) { nin := t.NumIn() if t.IsVariadic() { nin-- } var p *Parameter for i := 0; i < nin; i++ { p, err = parameterFromType(t.In(i)) if err != nil { return } in = append(in, p) } if t.IsVariadic() { p, err = parameterFromType(t.In(nin).Elem()) if err != nil { return } variadic = p } for i := 0; i < t.NumOut(); i++ { p, err = parameterFromType(t.Out(i)) if err != nil { return } out = append(out, p) } return }
func getInputTypeString(i int, ft reflect.Type) string { numInputs := ft.NumIn() if i == numInputs-1 && ft.IsVariadic() { return "..." + getTypeString(ft.In(i).Elem()) } return getTypeString(ft.In(i)) }
// safeNumericConvert converts numeric parameter val from js to the type that the function fn expects if its safe to do so. // This allows literals (int64) and the general js numeric form (float64) to be passed as parameters to go functions easily. func safeNumericConvert(fn reflect.Type, i int, val interface{}) reflect.Value { switch val.(type) { default: // Not a supported conversion return reflect.ValueOf(val) case float64, int64: // What type is the func expecting? var ptype reflect.Type switch { case fn.IsVariadic() && fn.NumIn() <= i+1: // This argument is variadic so use the variadics element type. ptype = fn.In(fn.NumIn() - 1).Elem() case fn.NumIn() > i: ptype = fn.In(i) } if f64, ok := val.(float64); ok { switch ptype.Kind() { case reflect.Float64: return reflect.ValueOf(val) case reflect.Float32: if reflect.Zero(ptype).OverflowFloat(f64) { // Not safe to convert return reflect.ValueOf(val) } return reflect.ValueOf(val).Convert(ptype) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: i64 := int64(f64) if float64(i64) != f64 { // Not safe to convert return reflect.ValueOf(val) } // The float represents an integer val = i64 default: // Not a supported conversion return reflect.ValueOf(val) } } i64 := val.(int64) switch ptype.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32: if !reflect.Zero(ptype).OverflowInt(i64) { return reflect.ValueOf(val).Convert(ptype) } case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: if i64 > 0 && !reflect.Zero(ptype).OverflowUint(uint64(i64)) { return reflect.ValueOf(val).Convert(ptype) } } } // Not a supported conversion return reflect.ValueOf(val) }
func (r concreteRunner) extractMethodArgs(runMethodType reflect.Type, protocolVersion ProtocolVersion, args []interface{}) (methodArgs []reflect.Value, err error) { numberOfArgs := runMethodType.NumIn() numberOfReqArgs := numberOfArgs if runMethodType.IsVariadic() { numberOfReqArgs-- } argsOffset := 0 if numberOfArgs > 0 { firstArgType := runMethodType.In(0) if firstArgType.Name() == "ProtocolVersion" { methodArgs = append(methodArgs, reflect.ValueOf(protocolVersion)) numberOfReqArgs-- argsOffset++ } } if len(args) < numberOfReqArgs { err = bosherr.Errorf("Not enough arguments, expected %d, got %d", numberOfReqArgs, len(args)) return } for i, argFromPayload := range args { var rawArgBytes []byte rawArgBytes, err = json.Marshal(argFromPayload) if err != nil { err = bosherr.WrapError(err, "Marshalling action argument") return } argType, typeFound := r.getMethodArgType(runMethodType, i+argsOffset) if !typeFound { continue } argValuePtr := reflect.New(argType) err = json.Unmarshal(rawArgBytes, argValuePtr.Interface()) if err != nil { err = bosherr.WrapError(err, "Unmarshalling action argument") return } methodArgs = append(methodArgs, reflect.Indirect(argValuePtr)) } return }
func (r JSONCaller) getMethodArgType(methodType reflect.Type, index int) (argType reflect.Type, found bool) { numberOfArgs := methodType.NumIn() switch { case !methodType.IsVariadic() && index >= numberOfArgs: return nil, false case methodType.IsVariadic() && index >= numberOfArgs-1: sliceType := methodType.In(numberOfArgs - 1) return sliceType.Elem(), true default: return methodType.In(index), true } }
// Funkcja sprawdza zgodnosc typow argumentow. Jesli to konieczne konwertuje // argumenty do typu interface{}. Jesli to potrzebne, funkcja odpowiednio // dostosowuje args dla funkcji. func argsMatch(ft reflect.Type, args []reflect.Value, method int) int { if ft.NumOut() == 0 { return RUN_NOT_RET } // Liczba arguemntow akceptowanych przez funkcje/metode num_in := ft.NumIn() - method // Sprawdzamy zgodnosc liczby argumentow i obecnosc funkcji dotdotdot var head_args, tail_args []reflect.Value if ft.IsVariadic() { num_in-- if len(args) < num_in { return RUN_WRONG_ARG_NUM } head_args = args[0:num_in] tail_args = args[num_in:] } else { if num_in != len(args) { return RUN_WRONG_ARG_NUM } head_args = args } // Sprawdzamy zgodnosc typow poczatkowych argumentow funkcji for kk, av := range head_args { at := ft.In(kk + method) // Typ argumentu if !av.Type().AssignableTo(at) { return RUN_WRONG_ARG_TYP } } if !ft.IsVariadic() { return RUN_OK } // Okreslamy typ argumentów zawartych w dotdotdot st := ft.In(ft.NumIn() - 1) // zawsze slice at := st.Elem() // Konkretny typ argumentu dotdotdot for _, av := range tail_args { if !av.Type().AssignableTo(at) { return RUN_WRONG_ARG_TYP } } return RUN_OK }
func (info *Info) TypeInfo(t reflect.Type) *Type { var name TypeName if t.Name() != "" { name = mkName(t.PkgPath(), t.Name()) } inPackage := t.PkgPath() != "" if inPackage && name != "" { if oldt := info.Types[name]; oldt != nil { if oldt.goType != nil && oldt.goType != t { panic(fmt.Errorf("duplicate type name with different types %q (%v)", name, t)) } return oldt } } jt := &Type{ Name: name, Kind: Kind(t.Kind().String()), goType: t, } if inPackage && name != "" { // Add the type to the info first to prevent infinite recursion. info.Types[name] = jt } info.addMethods(jt, t) switch t.Kind() { case reflect.Array, reflect.Chan, reflect.Ptr, reflect.Slice: jt.Elem = info.Ref(t.Elem()) case reflect.Map: jt.Key, jt.Elem = info.Ref(t.Key()), info.Ref(t.Elem()) case reflect.Struct: info.addFields(jt, t) case reflect.Func: jt.Variadic = t.IsVariadic() jt.In = make([]*Type, t.NumIn()) for i := range jt.In { jt.In[i] = info.Ref(t.In(i)) } jt.Out = make([]*Type, t.NumOut()) for i := range jt.Out { jt.Out[i] = info.Ref(t.Out(i)) } } return jt }
// getArgs retrieves argument list from args. // This tries to avoid common panics, and returns the corresponding errors instead. // panics can still occur but at least the ones related with arguments are mitigated. func getlArgs(typ reflect.Type, args []interface{}) ([]reflect.Value, error) { var rst []reflect.Value for _, v := range args { val := reflect.ValueOf(v) if !val.IsValid() { // eliminate zero value panic return nil, ErrZeroValue } rst = append(rst, val) } switch { case typ.IsVariadic(): if typ.NumIn() < len(args)-1 { // eliminate few argumenst panic return nil, ErrTooFewArgs } case !typ.IsVariadic() && typ.NumIn() > len(args): // eliminate too many arguments panic return nil, ErrTooManyArgs } return rst, nil }
func (r JSONCaller) extractMethodArgs(runMethodType reflect.Type, args []interface{}) (methodArgs []reflect.Value, err error) { numberOfArgs := runMethodType.NumIn() numberOfReqArgs := numberOfArgs if runMethodType.IsVariadic() { numberOfReqArgs-- } if len(args) < numberOfReqArgs { err = bosherr.Errorf("Not enough arguments, expected %d, got %d", numberOfReqArgs, len(args)) return } for i, argFromPayload := range args { var rawArgBytes []byte rawArgBytes, err = json.Marshal(argFromPayload) if err != nil { err = bosherr.WrapError(err, "Marshalling action argument") return } argType, typeFound := r.getMethodArgType(runMethodType, i) if !typeFound { continue } argValuePtr := reflect.New(argType) err = json.Unmarshal(rawArgBytes, argValuePtr.Interface()) if err != nil { err = bosherr.WrapError(err, "Unmarshalling action argument") return } methodArgs = append(methodArgs, reflect.Indirect(argValuePtr)) } return }
func newCtor(t reflect.Type, v reflect.Value) *ctor { if t.Kind() != reflect.Func || t.IsVariadic() { return nil } numOut := t.NumOut() if numOut == 0 || numOut > 2 || (numOut == 2 && t.Out(1) != terror) { return nil } outType := t.Out(0) numIn := t.NumIn() inTypes := make([]reflect.Type, numIn) for i := range inTypes { inTypes[i] = t.In(i) } construct := func(in []reflect.Value) (reflect.Value, error) { for i, arg := range in { if !arg.IsValid() { return reflect.Value{}, fmt.Errorf("unable to create arg %d (%s) of %s constructor <%v>", i, inTypes[i], outType, arg) } } out := v.Call(in) var err error if len(out) == 2 && !out[1].IsNil() { err = out[1].Interface().(error) } return out[0], err } return &ctor{ funcType: t, outType: outType, inTypes: inTypes, construct: construct, errChan: make(chan error), once: &sync.Once{}, } }
func (L *State) getFuncIn(ft rf.Type) []rf.Value { var in []rf.Value var i int for i = 0; i < ft.NumIn()-1; i++ { in = append(in, *L.getValueByType(ft.In(i).Kind(), i)) } switch { case ft.IsVariadic(): ek := ft.In(i).Elem().Kind() for ; i < int(C.lua_gettop(L.s)); i++ { switch ek { case rf.Interface: in = append(in, *L.getValueByLuaType(i)) default: in = append(in, *L.getValueByType(ek, i)) } } case i < ft.NumIn(): in = append(in, *L.getValueByType(ft.In(i).Kind(), i)) } return in }
func buildFactoryCallArguments(t reflect.Type, allParameters []interface{}) ([]reflect.Value, error) { actualNumberOfArgs := t.NumIn() args := make([]reflect.Value, len(allParameters)) for i, argument := range allParameters { var expectedArgumentType reflect.Type if t.IsVariadic() && i >= actualNumberOfArgs-1 { // variadic argument expectedArgumentType = t.In(actualNumberOfArgs - 1).Elem() } else { // regular argument expectedArgumentType = t.In(i) } args[i] = reflect.ValueOf(argument) if args[i].Kind() != expectedArgumentType.Kind() { if stringArg, isString := argument.(string); isString && !IsParameterOrTypeReference(stringArg) { return nil, fmt.Errorf("input argument %d is of type %s but needs to be a %s", i+1, args[i].Kind(), expectedArgumentType.Kind()) } } } return args, nil }
// TypeFromNative converts a regular Go type into a the corresponding // interpreter Type. func TypeFromNative(t reflect.Type) Type { if et, ok := evalTypes[t]; ok { return et } var nt *NamedType if t.Name() != "" { name := t.PkgPath() + "·" + t.Name() nt = &NamedType{token.NoPos, name, nil, true, make(map[string]Method)} evalTypes[t] = nt } var et Type switch t.Kind() { case reflect.Bool: et = BoolType case reflect.Float32: et = Float32Type case reflect.Float64: et = Float64Type case reflect.Int16: et = Int16Type case reflect.Int32: et = Int32Type case reflect.Int64: et = Int64Type case reflect.Int8: et = Int8Type case reflect.Int: et = IntType case reflect.Uint16: et = Uint16Type case reflect.Uint32: et = Uint32Type case reflect.Uint64: et = Uint64Type case reflect.Uint8: et = Uint8Type case reflect.Uint: et = UintType case reflect.Uintptr: et = UintptrType case reflect.String: et = StringType case reflect.Array: et = NewArrayType(int64(t.Len()), TypeFromNative(t.Elem())) case reflect.Chan: log.Panicf("%T not implemented", t) case reflect.Func: nin := t.NumIn() // Variadic functions have DotDotDotType at the end variadic := t.IsVariadic() if variadic { nin-- } in := make([]Type, nin) for i := range in { in[i] = TypeFromNative(t.In(i)) } out := make([]Type, t.NumOut()) for i := range out { out[i] = TypeFromNative(t.Out(i)) } et = NewFuncType(in, variadic, out) case reflect.Interface: log.Panicf("%T not implemented", t) case reflect.Map: et = NewMapType(TypeFromNative(t.Key()), TypeFromNative(t.Elem())) case reflect.Ptr: et = NewPtrType(TypeFromNative(t.Elem())) case reflect.Slice: et = NewSliceType(TypeFromNative(t.Elem())) case reflect.Struct: n := t.NumField() fields := make([]StructField, n) for i := 0; i < n; i++ { sf := t.Field(i) // TODO(austin) What to do about private fields? fields[i].Name = sf.Name fields[i].Type = TypeFromNative(sf.Type) fields[i].Anonymous = sf.Anonymous } et = NewStructType(fields) case reflect.UnsafePointer: log.Panicf("%T not implemented", t) default: log.Panicf("unexpected reflect.Type: %T", t) } if nt != nil { if _, ok := et.(*NamedType); !ok { nt.Complete(et) et = nt } } nativeTypes[et] = t evalTypes[t] = et return et }
func (p *Call) call(push bool, is []interface{}) (caller Caller) { defer func() { if err := recover(); err != nil { p.err = errors.New(fmt.Sprint(err)) } }() caller = p if p.failed || p.err != nil || len(is) == 0 { return } var fn reflect.Value var typ reflect.Type l := len(is) for i := 0; i < l; { fn = reflect.ValueOf(is[i]) if reflect.Func != fn.Kind() { p.args = append(p.args, is[i]) i++ continue } typ = fn.Type() la := typ.NumIn() numIn := 0 if typ.IsVariadic() || la != 0 { for j := 0; typ.IsVariadic() || j < la; j++ { i++ if i >= l || reflect.Func == reflect.TypeOf(is[i]).Kind() { break } p.args = append(p.args, is[i]) numIn++ } } else if la == 0 { i++ } la = len(p.args) if la < typ.NumIn() { p.setFailed(NotEnoughArgs) break } if !typ.IsVariadic() { numIn = typ.NumIn() } args := p.args[la-numIn:] p.args = p.args[:la-numIn] in := make([]reflect.Value, len(args)) for i, v := range args { in[i] = reflect.ValueOf(v) } out := fn.Call(in) la = len(out) // 总是保存输出 o := make([]interface{}, la) for i, v := range out { o[i] = v.Interface() } p.outs = append(p.outs, o) if la == 0 { continue } fn = out[la-1] switch fn.Kind().String() { case "bool": if !fn.Bool() { p.setFailed(Failed) return } la-- case "error": if !fn.IsNil() { p.setFailed(fn.Interface().(error)) return } la-- } // 输出压入备用参数 if !push { continue } for i := 0; i < la; i++ { p.args = append(p.args, out[i].Interface()) } } return }
func (client *BaseClient) remoteMethod(t reflect.Type, sf reflect.StructField) func(in []reflect.Value) []reflect.Value { name := getFuncName(&sf) options := &InvokeOptions{ByRef: getByRef(&sf), SimpleMode: getSimpleMode(&sf), ResultMode: getResultMode(&sf)} return func(in []reflect.Value) []reflect.Value { inlen := len(in) varlen := 0 argc := inlen if t.IsVariadic() { argc-- varlen = in[argc].Len() argc += varlen } args := make([]reflect.Value, argc) if argc > 0 { for i := 0; i < inlen-1; i++ { args[i] = in[i] } if t.IsVariadic() { v := in[inlen-1] for i := 0; i < varlen; i++ { args[inlen-1+i] = v.Index(i) } } else { args[inlen-1] = in[inlen-1] } } numout := t.NumOut() out := make([]reflect.Value, numout) switch numout { case 0: var result interface{} if err := <-client.invoke(name, args, options, []reflect.Value{reflect.ValueOf(&result).Elem()}); err == nil { return out } else { panic(err.Error()) } case 1: rt0 := t.Out(0) if rt0.Kind() == reflect.Chan { if rt0.Elem().Kind() == reflect.Interface && rt0.Elem().Name() == "error" { var result chan interface{} err := client.invoke(name, args, options, []reflect.Value{reflect.ValueOf(&result).Elem()}) out[0] = reflect.ValueOf(&err).Elem() return out } else { out[0] = reflect.New(rt0).Elem() client.invoke(name, args, options, out) return out } } else { if rt0.Kind() == reflect.Interface && rt0.Name() == "error" { var result interface{} err := <-client.invoke(name, args, options, []reflect.Value{reflect.ValueOf(&result).Elem()}) out[0] = reflect.ValueOf(&err).Elem() return out } else { out[0] = reflect.New(rt0).Elem() if err := <-client.invoke(name, args, options, out); err == nil { return out } else { panic(err.Error()) } } } default: last := numout - 1 rtlast := t.Out(last) for i := 0; i < last; i++ { out[i] = reflect.New(t.Out(i)).Elem() } if rtlast.Kind() == reflect.Chan && rtlast.Elem().Kind() == reflect.Interface && rtlast.Elem().Name() == "error" { err := client.invoke(name, args, options, out[:last]) out[last] = reflect.ValueOf(&err).Elem() return out } if rtlast.Kind() == reflect.Interface && rtlast.Name() == "error" { err := <-client.invoke(name, args, options, out[:last]) out[last] = reflect.ValueOf(&err).Elem() return out } out[last] = reflect.New(t.Out(last)).Elem() if t.Out(0).Kind() == reflect.Chan { client.invoke(name, args, options, out) return out } else { if err := <-client.invoke(name, args, options, out); err == nil { return out } else { panic(err.Error()) } } } return out } }
func inType(call reflect.Type, nthArg int) reflect.Type { if call.IsVariadic() && nthArg >= call.NumIn()-1 { return call.In(call.NumIn() - 1).Elem() } return call.In(nthArg) }
// argType returns the type of the nth argument to a function of type t. func argType(t reflect.Type, n int) reflect.Type { if !t.IsVariadic() || n < t.NumIn()-1 { return t.In(n) } return t.In(t.NumIn() - 1).Elem() }
func makeTrampoline(typ reflect.Type, handle unsafe.Pointer) (rFunc, error) { numOut := typ.NumOut() if numOut > 1 { return nil, fmt.Errorf("C functions can return 0 or 1 values, not %d", numOut) } var out reflect.Type var kind reflect.Kind outFlag := C.int(0) if numOut == 1 { out = typ.Out(0) kind = out.Kind() if kind == reflect.Float32 || kind == reflect.Float64 { outFlag |= C.ARG_FLAG_FLOAT } } return func(in []reflect.Value) []reflect.Value { if typ.IsVariadic() && len(in) > 0 { last := in[len(in)-1] in = in[:len(in)-1] if last.Len() > 0 { for ii := 0; ii < last.Len(); ii++ { in = append(in, last.Index(ii)) } } } count := len(in) args := make([]unsafe.Pointer, count) flags := make([]C.int, count+1) flags[count] = outFlag for ii, v := range in { if v.Type() == emptyType { v = reflect.ValueOf(v.Interface()) } switch v.Kind() { case reflect.String: s := C.CString(v.String()) defer C.free(unsafe.Pointer(s)) args[ii] = unsafe.Pointer(s) flags[ii] |= C.ARG_FLAG_SIZE_PTR case reflect.Int: args[ii] = unsafe.Pointer(uintptr(v.Int())) if v.Type().Size() == 4 { flags[ii] = C.ARG_FLAG_SIZE_32 } else { flags[ii] = C.ARG_FLAG_SIZE_64 } case reflect.Int8: args[ii] = unsafe.Pointer(uintptr(v.Int())) flags[ii] = C.ARG_FLAG_SIZE_8 case reflect.Int16: args[ii] = unsafe.Pointer(uintptr(v.Int())) flags[ii] = C.ARG_FLAG_SIZE_16 case reflect.Int32: args[ii] = unsafe.Pointer(uintptr(v.Int())) flags[ii] = C.ARG_FLAG_SIZE_32 case reflect.Int64: args[ii] = unsafe.Pointer(uintptr(v.Int())) flags[ii] = C.ARG_FLAG_SIZE_64 case reflect.Uint: args[ii] = unsafe.Pointer(uintptr(v.Uint())) if v.Type().Size() == 4 { flags[ii] = C.ARG_FLAG_SIZE_32 } else { flags[ii] = C.ARG_FLAG_SIZE_64 } case reflect.Uint8: args[ii] = unsafe.Pointer(uintptr(v.Uint())) flags[ii] = C.ARG_FLAG_SIZE_8 case reflect.Uint16: args[ii] = unsafe.Pointer(uintptr(v.Uint())) flags[ii] = C.ARG_FLAG_SIZE_16 case reflect.Uint32: args[ii] = unsafe.Pointer(uintptr(v.Uint())) flags[ii] = C.ARG_FLAG_SIZE_32 case reflect.Uint64: args[ii] = unsafe.Pointer(uintptr(v.Uint())) flags[ii] = C.ARG_FLAG_SIZE_64 case reflect.Float32: args[ii] = unsafe.Pointer(uintptr(math.Float32bits(float32(v.Float())))) flags[ii] |= C.ARG_FLAG_FLOAT | C.ARG_FLAG_SIZE_32 case reflect.Float64: args[ii] = unsafe.Pointer(uintptr(math.Float64bits(v.Float()))) flags[ii] |= C.ARG_FLAG_FLOAT | C.ARG_FLAG_SIZE_64 case reflect.Ptr: args[ii] = unsafe.Pointer(v.Pointer()) flags[ii] |= C.ARG_FLAG_SIZE_PTR case reflect.Slice: if v.Len() > 0 { args[ii] = unsafe.Pointer(v.Index(0).UnsafeAddr()) } flags[ii] |= C.ARG_FLAG_SIZE_PTR case reflect.Uintptr: args[ii] = unsafe.Pointer(uintptr(v.Uint())) flags[ii] |= C.ARG_FLAG_SIZE_PTR default: panic(fmt.Errorf("can't bind value of type %s", v.Type())) } } var argp *unsafe.Pointer if count > 0 { argp = &args[0] } var ret unsafe.Pointer if C.call(handle, argp, &flags[0], C.int(count), &ret) != 0 { s := C.GoString((*C.char)(ret)) C.free(ret) panic(errors.New(s)) } if numOut > 0 { var v reflect.Value switch kind { case reflect.Int: v = reflect.ValueOf(int(uintptr(ret))) case reflect.Int8: v = reflect.ValueOf(int8(uintptr(ret))) case reflect.Int16: v = reflect.ValueOf(int16(uintptr(ret))) case reflect.Int32: v = reflect.ValueOf(int32(uintptr(ret))) case reflect.Int64: v = reflect.ValueOf(int64(uintptr(ret))) case reflect.Uint: v = reflect.ValueOf(uint(uintptr(ret))) case reflect.Uint8: v = reflect.ValueOf(uint8(uintptr(ret))) case reflect.Uint16: v = reflect.ValueOf(uint16(uintptr(ret))) case reflect.Uint32: v = reflect.ValueOf(uint32(uintptr(ret))) case reflect.Uint64: v = reflect.ValueOf(uint64(uintptr(ret))) case reflect.Float32: v = reflect.ValueOf(math.Float32frombits(uint32(uintptr(ret)))) case reflect.Float64: v = reflect.ValueOf(math.Float64frombits(uint64(uintptr(ret)))) case reflect.Ptr: if out.Elem().Kind() == reflect.String && ret != nil { s := C.GoString((*C.char)(ret)) v = reflect.ValueOf(&s) break } v = reflect.NewAt(out.Elem(), ret) case reflect.String: s := C.GoString((*C.char)(ret)) v = reflect.ValueOf(s) case reflect.Uintptr: v = reflect.ValueOf(uintptr(ret)) case reflect.UnsafePointer: v = reflect.ValueOf(ret) default: panic(fmt.Errorf("can't retrieve value of type %s", out)) } return []reflect.Value{v} } return nil }, nil }