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  }