github.com/isyscore/isc-gobase@v1.5.3-0.20231218061332-cbc7451899e9/jvm/vmargs.go (about) 1 package jvm 2 3 import ( 4 "fmt" 5 "reflect" 6 "strings" 7 "unsafe" 8 ) 9 10 /* 11 #include <stdlib.h> 12 #include <jni.h> 13 */ 14 import "C" 15 16 func ArgumentsCheck(args ...any) ([]string, error) { 17 var types []string 18 var err error 19 for _, a := range args { 20 t := reflect.TypeOf(a).String() 21 if t == "bool" { 22 types = append(types, "Z") 23 } else if t == "uint8" { 24 types = append(types, "B") 25 } else if t == "int16" { 26 types = append(types, "S") 27 } else if t == "int64" { 28 types = append(types, "J") 29 } else if t == "float32" { 30 types = append(types, "F") 31 } else if t == "float64" { 32 types = append(types, "D") 33 } else if t == "string" { 34 types = append(types, "Ljava/lang/String;") 35 } else if strings.Contains(t, "int") { 36 types = append(types, "I") 37 } else { 38 err = fmt.Errorf("unsupported type: %s", t) 39 } 40 } 41 return types, err 42 } 43 44 func ParseArguments(types []string, retType string, args ...any) (string, **C.char, *unsafe.Pointer) { 45 size := C.size_t(unsafe.Sizeof((*C.char)(nil))) 46 clen := C.size_t(len(args)) 47 typesArg := (**C.char)(C.malloc(size * clen)) 48 typesArgView := (*[1 << 30]*C.char)(unsafe.Pointer(typesArg))[0:len(args):len(args)] 49 sizev := C.size_t(unsafe.Sizeof((*C.void)(nil))) 50 argArg := (*unsafe.Pointer)(C.malloc(sizev * clen)) 51 argArgView := (*[1 << 30]unsafe.Pointer)(unsafe.Pointer(argArg))[0:len(args):len(args)] 52 53 sigStr := "(" 54 for i, t := range types { 55 sigStr += t 56 typesArgView[i] = C.CString(t) 57 if t == "Ljava/lang/String;" { 58 argArgView[i] = unsafe.Pointer(C.CString(args[i].(string))) 59 } else if t == "I" { 60 ci := C.int(args[i].(int)) 61 argArgView[i] = unsafe.Pointer(&ci) 62 } else if t == "J" { 63 li := C.long(args[i].(int64)) 64 argArgView[i] = unsafe.Pointer(&li) 65 } else if t == "Z" { 66 var bi C.int 67 if args[i].(bool) { 68 bi = 1 69 } else { 70 bi = 0 71 } 72 argArgView[i] = unsafe.Pointer(&bi) 73 } else if t == "S" { 74 si := C.short(args[i].(int16)) 75 argArgView[i] = unsafe.Pointer(&si) 76 } else if t == "F" { 77 fi := C.float(args[i].(float32)) 78 argArgView[i] = unsafe.Pointer(&fi) 79 } else if t == "D" { 80 di := C.double(args[i].(float64)) 81 argArgView[i] = unsafe.Pointer(&di) 82 } else if t == "B" { 83 bi := C.uchar(args[i].(uint8)) 84 argArgView[i] = unsafe.Pointer(&bi) 85 } 86 } 87 sigStr += ")" + retType 88 return sigStr, typesArg, argArg 89 } 90 91 func FreeArgs(size int, types []string, typesArg **C.char, valArgs *unsafe.Pointer) { 92 typView := (*[1 << 30]*C.char)(unsafe.Pointer(typesArg))[0:size:size] 93 valView := (*[1 << 30]unsafe.Pointer)(unsafe.Pointer(valArgs))[0:size:size] 94 for i := 0; i < size; i++ { 95 C.free(unsafe.Pointer(typView[i])) 96 if types[i] == "Ljava/lang/String;" { 97 C.free(valView[i]) 98 } 99 } 100 C.free(unsafe.Pointer(typesArg)) 101 C.free(unsafe.Pointer(valArgs)) 102 } 103 104 func ParseNameSig(name string, sig string) (*C.char, *C.char) { 105 nameC := C.CString(name) 106 sigC := C.CString(sig) 107 return nameC, sigC 108 } 109 110 func FreeNameSig(nameC *C.char, sigC *C.char) { 111 C.free(unsafe.Pointer(nameC)) 112 C.free(unsafe.Pointer(sigC)) 113 }