github.com/isyscore/isc-gobase@v1.5.3-0.20231218061332-cbc7451899e9/jvm/gojvm.go (about)

     1  package jvm
     2  
     3  // 需要引用jni,先将jni相关的头文件链接到 /usr/local/include
     4  // 所需文件为 jni.h, jni_md.h
     5  // 同时需要将 libjvm.so/libjvm.dylib 链接到 /usr/local/lib
     6  
     7  //#cgo CFLAGS: -I/usr/local/include
     8  //#cgo LDFLAGS: -L/usr/local/lib -ljvm
     9  /*
    10  #include "gojvm_c.h"
    11  */
    12  import "C"
    13  import (
    14  	"strings"
    15  	"unsafe"
    16  )
    17  
    18  type JavaVM struct {
    19  	jvm *C.JavaVM
    20  }
    21  
    22  type JavaEnv struct {
    23  	jvm *C.JavaVM
    24  	env *C.JNIEnv
    25  }
    26  
    27  type JavaClass struct {
    28  	jvm       *C.JavaVM
    29  	env       *C.JNIEnv
    30  	clazz     C.jclass
    31  	ClassName string
    32  }
    33  
    34  type JavaObject struct {
    35  	jvm       *C.JavaVM
    36  	env       *C.JNIEnv
    37  	clazz     C.jclass
    38  	obj       C.jobject
    39  	ClassName string
    40  }
    41  
    42  //=============================================================
    43  // jvm
    44  //=============================================================
    45  
    46  func NewJVM(classPath string, xms string, xmx string, xmn string, xss string) *JavaVM {
    47  	cpath := C.CString(classPath)
    48  	cxms := C.CString(xms)
    49  	cxmx := C.CString(xmx)
    50  	cxmn := C.CString(xmn)
    51  	cxss := C.CString(xss)
    52  	defer C.free(unsafe.Pointer(cpath))
    53  	defer C.free(unsafe.Pointer(cxms))
    54  	defer C.free(unsafe.Pointer(cxmx))
    55  	defer C.free(unsafe.Pointer(cxmn))
    56  	defer C.free(unsafe.Pointer(cxss))
    57  
    58  	jvm := C.createJvm(cpath, cxms, cxmx, cxmn, cxss)
    59  	if jvm == nil {
    60  		return nil
    61  	}
    62  
    63  	return &JavaVM{jvm: jvm}
    64  }
    65  
    66  func (vm *JavaVM) Free() {
    67  	_ = C.destroyJvm(vm.jvm)
    68  }
    69  
    70  func (vm *JavaVM) Attach() *JavaEnv {
    71  	env := C.attachJvm(vm.jvm)
    72  	if env == nil {
    73  		return nil
    74  	}
    75  	return &JavaEnv{
    76  		jvm: vm.jvm,
    77  		env: env,
    78  	}
    79  }
    80  
    81  //=============================================================
    82  // env
    83  //=============================================================
    84  
    85  func (env *JavaEnv) Detach() {
    86  	C.detachJvm(env.jvm)
    87  }
    88  
    89  func (env *JavaEnv) FindClass(className string) *JavaClass {
    90  	cn := strings.ReplaceAll(className, ".", "/")
    91  	cname := C.CString(cn)
    92  	defer C.free(unsafe.Pointer(cname))
    93  	clazz := C.findClass(env.env, cname)
    94  	if clazz == 0 {
    95  		return nil
    96  	}
    97  	return &JavaClass{
    98  		jvm:       env.jvm,
    99  		env:       env.env,
   100  		clazz:     clazz,
   101  		ClassName: className,
   102  	}
   103  }
   104  
   105  func (env *JavaEnv) NewObject(className string) *JavaObject {
   106  	jc := env.FindClass(className)
   107  	if jc == nil {
   108  		return nil
   109  	}
   110  	jo := C.newJavaObject(env.env, jc.clazz)
   111  	if jo == C.jobject(C.NULL) {
   112  		return nil
   113  	}
   114  	return &JavaObject{
   115  		jvm:       env.jvm,
   116  		env:       env.env,
   117  		clazz:     jc.clazz,
   118  		obj:       jo,
   119  		ClassName: className,
   120  	}
   121  }
   122  
   123  //=============================================================
   124  // class
   125  //=============================================================
   126  
   127  func (c *JavaClass) NewObject() *JavaObject {
   128  	jo := C.newJavaObject(c.env, c.clazz)
   129  	if jo == C.jobject(C.NULL) {
   130  		return nil
   131  	}
   132  	return &JavaObject{
   133  		jvm:       c.jvm,
   134  		env:       c.env,
   135  		clazz:     c.clazz,
   136  		obj:       jo,
   137  		ClassName: c.ClassName,
   138  	}
   139  }
   140  
   141  func (c *JavaClass) InvokeVoid(methodName string, args ...any) error {
   142  	types, err := ArgumentsCheck(args...)
   143  	if err != nil {
   144  		return err
   145  	}
   146  	sigStr, typArg, valArg := ParseArguments(types, "V", args...)
   147  	defer FreeArgs(len(args), types, typArg, valArg)
   148  	cmn, csig := ParseNameSig(methodName, sigStr)
   149  	defer FreeNameSig(cmn, csig)
   150  	clen := C.int(len(args))
   151  	C.callStaticVoidMethod(c.env, c.clazz, cmn, csig, clen, typArg, valArg)
   152  	return nil
   153  }
   154  
   155  func (c *JavaClass) InvokeObject(methodName string, retClassName string, args ...any) (*JavaObject, error) {
   156  	types, err := ArgumentsCheck(args...)
   157  	if err != nil {
   158  		return nil, err
   159  	}
   160  	objsig := "L" + strings.ReplaceAll(retClassName, ".", "/") + ";"
   161  	sigStr, typArg, valArg := ParseArguments(types, objsig, args...)
   162  	defer FreeArgs(len(args), types, typArg, valArg)
   163  	cmn, csig := ParseNameSig(methodName, sigStr)
   164  	defer FreeNameSig(cmn, csig)
   165  	clen := C.int(len(args))
   166  	jo := C.callStaticObjectMethod(c.env, c.clazz, cmn, csig, clen, typArg, valArg)
   167  	if jo == C.jobject(C.NULL) {
   168  		return nil, nil
   169  	}
   170  	return &JavaObject{
   171  		jvm:       c.jvm,
   172  		env:       c.env,
   173  		clazz:     C.getObjectClass(c.env, jo),
   174  		obj:       jo,
   175  		ClassName: retClassName,
   176  	}, nil
   177  }
   178  
   179  func (c *JavaClass) InvokeString(methodName string, args ...any) (string, error) {
   180  	types, err := ArgumentsCheck(args...)
   181  	if err != nil {
   182  		return "", err
   183  	}
   184  	sigStr, typArg, valArg := ParseArguments(types, "Ljava/lang/String;", args...)
   185  	defer FreeArgs(len(args), types, typArg, valArg)
   186  	cmn, csig := ParseNameSig(methodName, sigStr)
   187  	defer FreeNameSig(cmn, csig)
   188  	clen := C.int(len(args))
   189  	ret := C.callStaticStringMethod(c.env, c.clazz, cmn, csig, clen, typArg, valArg)
   190  	if ret == nil {
   191  		return "", nil
   192  	}
   193  	defer C.free(unsafe.Pointer(ret))
   194  	return C.GoString(ret), nil
   195  }
   196  
   197  func (c *JavaClass) InvokeInt(methodName string, args ...any) (int, error) {
   198  	types, err := ArgumentsCheck(args...)
   199  	if err != nil {
   200  		return 0, err
   201  	}
   202  	sigStr, typArg, valArg := ParseArguments(types, "I", args...)
   203  	defer FreeArgs(len(args), types, typArg, valArg)
   204  	cmn, csig := ParseNameSig(methodName, sigStr)
   205  	defer FreeNameSig(cmn, csig)
   206  	clen := C.int(len(args))
   207  	ret := C.callStaticIntMethod(c.env, c.clazz, cmn, csig, clen, typArg, valArg)
   208  	return int(ret), nil
   209  }
   210  
   211  func (c *JavaClass) InvokeLong(methodName string, args ...any) (int64, error) {
   212  	types, err := ArgumentsCheck(args...)
   213  	if err != nil {
   214  		return 0, err
   215  	}
   216  	sigStr, typArg, valArg := ParseArguments(types, "I", args...)
   217  	defer FreeArgs(len(args), types, typArg, valArg)
   218  	cmn, csig := ParseNameSig(methodName, sigStr)
   219  	defer FreeNameSig(cmn, csig)
   220  	clen := C.int(len(args))
   221  	ret := C.callStaticLongMethod(c.env, c.clazz, cmn, csig, clen, typArg, valArg)
   222  	return int64(ret), nil
   223  }
   224  
   225  func (c *JavaClass) InvokeShort(methodName string, args ...any) (int16, error) {
   226  	types, err := ArgumentsCheck(args...)
   227  	if err != nil {
   228  		return 0, err
   229  	}
   230  	sigStr, typArg, valArg := ParseArguments(types, "I", args...)
   231  	defer FreeArgs(len(args), types, typArg, valArg)
   232  	cmn, csig := ParseNameSig(methodName, sigStr)
   233  	defer FreeNameSig(cmn, csig)
   234  	clen := C.int(len(args))
   235  	ret := C.callStaticShortMethod(c.env, c.clazz, cmn, csig, clen, typArg, valArg)
   236  	return int16(ret), nil
   237  }
   238  
   239  func (c *JavaClass) InvokeByte(methodName string, args ...any) (uint8, error) {
   240  	types, err := ArgumentsCheck(args...)
   241  	if err != nil {
   242  		return 0, err
   243  	}
   244  	sigStr, typArg, valArg := ParseArguments(types, "I", args...)
   245  	defer FreeArgs(len(args), types, typArg, valArg)
   246  	cmn, csig := ParseNameSig(methodName, sigStr)
   247  	defer FreeNameSig(cmn, csig)
   248  	clen := C.int(len(args))
   249  	ret := C.callStaticByteMethod(c.env, c.clazz, cmn, csig, clen, typArg, valArg)
   250  	return uint8(ret), nil
   251  }
   252  
   253  func (c *JavaClass) InvokeFloat(methodName string, args ...any) (float32, error) {
   254  	types, err := ArgumentsCheck(args...)
   255  	if err != nil {
   256  		return 0, err
   257  	}
   258  	sigStr, typArg, valArg := ParseArguments(types, "I", args...)
   259  	defer FreeArgs(len(args), types, typArg, valArg)
   260  	cmn, csig := ParseNameSig(methodName, sigStr)
   261  	defer FreeNameSig(cmn, csig)
   262  	clen := C.int(len(args))
   263  	ret := C.callStaticFloatMethod(c.env, c.clazz, cmn, csig, clen, typArg, valArg)
   264  	return float32(ret), nil
   265  }
   266  
   267  func (c *JavaClass) InvokeDouble(methodName string, args ...any) (float64, error) {
   268  	types, err := ArgumentsCheck(args...)
   269  	if err != nil {
   270  		return 0, err
   271  	}
   272  	sigStr, typArg, valArg := ParseArguments(types, "I", args...)
   273  	defer FreeArgs(len(args), types, typArg, valArg)
   274  	cmn, csig := ParseNameSig(methodName, sigStr)
   275  	defer FreeNameSig(cmn, csig)
   276  	clen := C.int(len(args))
   277  	ret := C.callStaticDoubleMethod(c.env, c.clazz, cmn, csig, clen, typArg, valArg)
   278  	return float64(ret), nil
   279  }
   280  
   281  func (c *JavaClass) InvokeBoolean(methodName string, args ...any) (bool, error) {
   282  	types, err := ArgumentsCheck(args...)
   283  	if err != nil {
   284  		return false, err
   285  	}
   286  	sigStr, typArg, valArg := ParseArguments(types, "I", args...)
   287  	defer FreeArgs(len(args), types, typArg, valArg)
   288  	cmn, csig := ParseNameSig(methodName, sigStr)
   289  	defer FreeNameSig(cmn, csig)
   290  	clen := C.int(len(args))
   291  	ret := C.callStaticBooleanMethod(c.env, c.clazz, cmn, csig, clen, typArg, valArg)
   292  	return int(ret) != 0, nil
   293  }
   294  
   295  func (c *JavaClass) GetObject(fieldName string, className string) *JavaObject {
   296  	sig := strings.ReplaceAll(className, ".", "/")
   297  	cmn, csig := ParseNameSig(fieldName, "L"+sig+";")
   298  	defer FreeNameSig(cmn, csig)
   299  	ret := C.getStaticObject(c.env, c.clazz, cmn, csig)
   300  	if ret == C.jobject(C.NULL) {
   301  		return nil
   302  	}
   303  	return &JavaObject{
   304  		jvm:       c.jvm,
   305  		env:       c.env,
   306  		clazz:     C.findClass(c.env, csig),
   307  		obj:       ret,
   308  		ClassName: className,
   309  	}
   310  }
   311  
   312  func (c *JavaClass) SetObject(fieldName string, className string, obj *JavaObject) {
   313  	sig := strings.ReplaceAll(className, ".", "/")
   314  	cmn, csig := ParseNameSig(fieldName, "L"+sig+";")
   315  	defer FreeNameSig(cmn, csig)
   316  	C.setStaticObject(c.env, c.clazz, cmn, csig, obj.obj)
   317  }
   318  
   319  func (c *JavaClass) GetString(fieldName string) string {
   320  	cmn := C.CString(fieldName)
   321  	defer C.free(unsafe.Pointer(cmn))
   322  	ret := C.getStaticString(c.env, c.clazz, cmn)
   323  	if ret == nil {
   324  		return ""
   325  	}
   326  	defer C.free(unsafe.Pointer(ret))
   327  	return C.GoString(ret)
   328  }
   329  
   330  func (c *JavaClass) SetString(fieldName string, value string) {
   331  	cmn := C.CString(fieldName)
   332  	defer C.free(unsafe.Pointer(cmn))
   333  	cval := C.CString(value)
   334  	defer C.free(unsafe.Pointer(cval))
   335  	C.setStaticString(c.env, c.clazz, cmn, cval)
   336  }
   337  
   338  func (c *JavaClass) GetInt(fieldName string) int {
   339  	cmn := C.CString(fieldName)
   340  	defer C.free(unsafe.Pointer(cmn))
   341  	ret := C.getStaticInt(c.env, c.clazz, cmn)
   342  	return int(ret)
   343  }
   344  
   345  func (c *JavaClass) SetInt(fieldName string, value int) {
   346  	cmn := C.CString(fieldName)
   347  	defer C.free(unsafe.Pointer(cmn))
   348  	C.setStaticInt(c.env, c.clazz, cmn, C.int(value))
   349  }
   350  
   351  func (c *JavaClass) GetLong(fieldName string) int64 {
   352  	cmn := C.CString(fieldName)
   353  	defer C.free(unsafe.Pointer(cmn))
   354  	ret := C.getStaticLong(c.env, c.clazz, cmn)
   355  	return int64(ret)
   356  }
   357  
   358  func (c *JavaClass) SetLong(fieldName string, value int64) {
   359  	cmn := C.CString(fieldName)
   360  	defer C.free(unsafe.Pointer(cmn))
   361  	C.setStaticLong(c.env, c.clazz, cmn, C.long(value))
   362  }
   363  
   364  func (c *JavaClass) GetShort(fieldName string) int16 {
   365  	cmn := C.CString(fieldName)
   366  	defer C.free(unsafe.Pointer(cmn))
   367  	ret := C.getStaticShort(c.env, c.clazz, cmn)
   368  	return int16(ret)
   369  }
   370  
   371  func (c *JavaClass) SetShort(fieldName string, value int16) {
   372  	cmn := C.CString(fieldName)
   373  	defer C.free(unsafe.Pointer(cmn))
   374  	C.setStaticShort(c.env, c.clazz, cmn, C.short(value))
   375  }
   376  
   377  func (c *JavaClass) GetByte(fieldName string) uint8 {
   378  	cmn := C.CString(fieldName)
   379  	defer C.free(unsafe.Pointer(cmn))
   380  	ret := C.getStaticByte(c.env, c.clazz, cmn)
   381  	return uint8(ret)
   382  }
   383  
   384  func (c *JavaClass) SetByte(fieldName string, value uint8) {
   385  	cmn := C.CString(fieldName)
   386  	defer C.free(unsafe.Pointer(cmn))
   387  	C.setStaticByte(c.env, c.clazz, cmn, C.uchar(value))
   388  }
   389  
   390  func (c *JavaClass) GetFloat(fieldName string) float32 {
   391  	cmn := C.CString(fieldName)
   392  	defer C.free(unsafe.Pointer(cmn))
   393  	ret := C.getStaticFloat(c.env, c.clazz, cmn)
   394  	return float32(ret)
   395  }
   396  
   397  func (c *JavaClass) SetFloat(fieldName string, value float32) {
   398  	cmn := C.CString(fieldName)
   399  	defer C.free(unsafe.Pointer(cmn))
   400  	C.setStaticFloat(c.env, c.clazz, cmn, C.float(value))
   401  }
   402  
   403  func (c *JavaClass) GetDouble(fieldName string) float64 {
   404  	cmn := C.CString(fieldName)
   405  	defer C.free(unsafe.Pointer(cmn))
   406  	ret := C.getStaticDouble(c.env, c.clazz, cmn)
   407  	return float64(ret)
   408  }
   409  
   410  func (c *JavaClass) SetDouble(fieldName string, value float64) {
   411  	cmn := C.CString(fieldName)
   412  	defer C.free(unsafe.Pointer(cmn))
   413  	C.setStaticDouble(c.env, c.clazz, cmn, C.double(value))
   414  }
   415  
   416  func (c *JavaClass) GetBoolean(fieldName string) bool {
   417  	cmn := C.CString(fieldName)
   418  	defer C.free(unsafe.Pointer(cmn))
   419  	ret := C.getStaticBoolean(c.env, c.clazz, cmn)
   420  	return ret != 0
   421  }
   422  
   423  func (c *JavaClass) SetBoolean(fieldName string, value bool) {
   424  	cmn := C.CString(fieldName)
   425  	defer C.free(unsafe.Pointer(cmn))
   426  	var b C.int
   427  	if value {
   428  		b = 1
   429  	} else {
   430  		b = 0
   431  	}
   432  	C.setStaticBoolean(c.env, c.clazz, cmn, b)
   433  }
   434  
   435  func (c *JavaClass) Free() {
   436  	C.freeJavaClassRef(c.env, c.clazz)
   437  }
   438  
   439  //=============================================================
   440  // class
   441  //=============================================================
   442  
   443  func (o *JavaObject) Free() {
   444  	C.freeJavaClassRef(o.env, o.clazz)
   445  	C.freeJavaObject(o.env, o.obj)
   446  }
   447  
   448  func (o *JavaObject) InvokeVoid(methodName string, args ...any) error {
   449  	types, err := ArgumentsCheck(args...)
   450  	if err != nil {
   451  		return err
   452  	}
   453  	sigStr, typArg, valArg := ParseArguments(types, "V", args...)
   454  	defer FreeArgs(len(args), types, typArg, valArg)
   455  	cmn, csig := ParseNameSig(methodName, sigStr)
   456  	defer FreeNameSig(cmn, csig)
   457  	clen := C.int(len(args))
   458  	C.callVoidMethod(o.env, o.clazz, o.obj, cmn, csig, clen, typArg, valArg)
   459  	return nil
   460  }
   461  
   462  func (o *JavaObject) InvokeObject(methodName string, retClassName string, args ...any) (*JavaObject, error) {
   463  	types, err := ArgumentsCheck(args...)
   464  	if err != nil {
   465  		return nil, err
   466  	}
   467  	objsig := "L" + strings.ReplaceAll(retClassName, ".", "/") + ";"
   468  	sigStr, typArg, valArg := ParseArguments(types, objsig, args...)
   469  	defer FreeArgs(len(args), types, typArg, valArg)
   470  	cmn, csig := ParseNameSig(methodName, sigStr)
   471  	defer FreeNameSig(cmn, csig)
   472  	clen := C.int(len(args))
   473  	jo := C.callObjectMethod(o.env, o.clazz, o.obj, cmn, csig, clen, typArg, valArg)
   474  	if jo == C.jobject(C.NULL) {
   475  		return nil, nil
   476  	}
   477  	return &JavaObject{
   478  		jvm:       o.jvm,
   479  		env:       o.env,
   480  		clazz:     C.getObjectClass(o.env, jo),
   481  		obj:       jo,
   482  		ClassName: retClassName,
   483  	}, nil
   484  }
   485  
   486  func (o *JavaObject) InvokeString(methodName string, args ...any) (string, error) {
   487  	types, err := ArgumentsCheck(args...)
   488  	if err != nil {
   489  		return "", err
   490  	}
   491  	sigStr, typArg, valArg := ParseArguments(types, "Ljava/lang/String;", args...)
   492  	defer FreeArgs(len(args), types, typArg, valArg)
   493  	cmn, csig := ParseNameSig(methodName, sigStr)
   494  	defer FreeNameSig(cmn, csig)
   495  	clen := C.int(len(args))
   496  	ret := C.callStringMethod(o.env, o.clazz, o.obj, cmn, csig, clen, typArg, valArg)
   497  	if ret == nil {
   498  		return "", nil
   499  	}
   500  	defer C.free(unsafe.Pointer(ret))
   501  	return C.GoString(ret), nil
   502  }
   503  
   504  func (o *JavaObject) InvokeInt(methodName string, args ...any) (int, error) {
   505  	types, err := ArgumentsCheck(args...)
   506  	if err != nil {
   507  		return 0, err
   508  	}
   509  	sigStr, typArg, valArg := ParseArguments(types, "I", args...)
   510  	defer FreeArgs(len(args), types, typArg, valArg)
   511  	cmn, csig := ParseNameSig(methodName, sigStr)
   512  	defer FreeNameSig(cmn, csig)
   513  	clen := C.int(len(args))
   514  	ret := C.callIntMethod(o.env, o.clazz, o.obj, cmn, csig, clen, typArg, valArg)
   515  	return int(ret), nil
   516  }
   517  
   518  func (o *JavaObject) InvokeLong(methodName string, args ...any) (int64, error) {
   519  	types, err := ArgumentsCheck(args...)
   520  	if err != nil {
   521  		return 0, err
   522  	}
   523  	sigStr, typArg, valArg := ParseArguments(types, "I", args...)
   524  	defer FreeArgs(len(args), types, typArg, valArg)
   525  	cmn, csig := ParseNameSig(methodName, sigStr)
   526  	defer FreeNameSig(cmn, csig)
   527  	clen := C.int(len(args))
   528  	ret := C.callLongMethod(o.env, o.clazz, o.obj, cmn, csig, clen, typArg, valArg)
   529  	return int64(ret), nil
   530  }
   531  
   532  func (o *JavaObject) InvokeShort(methodName string, args ...any) (int16, error) {
   533  	types, err := ArgumentsCheck(args...)
   534  	if err != nil {
   535  		return 0, err
   536  	}
   537  	sigStr, typArg, valArg := ParseArguments(types, "I", args...)
   538  	defer FreeArgs(len(args), types, typArg, valArg)
   539  	cmn, csig := ParseNameSig(methodName, sigStr)
   540  	defer FreeNameSig(cmn, csig)
   541  	clen := C.int(len(args))
   542  	ret := C.callShortMethod(o.env, o.clazz, o.obj, cmn, csig, clen, typArg, valArg)
   543  	return int16(ret), nil
   544  }
   545  
   546  func (o *JavaObject) InvokeByte(methodName string, args ...any) (uint8, error) {
   547  	types, err := ArgumentsCheck(args...)
   548  	if err != nil {
   549  		return 0, err
   550  	}
   551  	sigStr, typArg, valArg := ParseArguments(types, "I", args...)
   552  	defer FreeArgs(len(args), types, typArg, valArg)
   553  	cmn, csig := ParseNameSig(methodName, sigStr)
   554  	defer FreeNameSig(cmn, csig)
   555  	clen := C.int(len(args))
   556  	ret := C.callByteMethod(o.env, o.clazz, o.obj, cmn, csig, clen, typArg, valArg)
   557  	return uint8(ret), nil
   558  }
   559  
   560  func (o *JavaObject) InvokeFloat(methodName string, args ...any) (float32, error) {
   561  	types, err := ArgumentsCheck(args...)
   562  	if err != nil {
   563  		return 0, err
   564  	}
   565  	sigStr, typArg, valArg := ParseArguments(types, "I", args...)
   566  	defer FreeArgs(len(args), types, typArg, valArg)
   567  	cmn, csig := ParseNameSig(methodName, sigStr)
   568  	defer FreeNameSig(cmn, csig)
   569  	clen := C.int(len(args))
   570  	ret := C.callFloatMethod(o.env, o.clazz, o.obj, cmn, csig, clen, typArg, valArg)
   571  	return float32(ret), nil
   572  }
   573  
   574  func (o *JavaObject) InvokeDouble(methodName string, args ...any) (float64, error) {
   575  	types, err := ArgumentsCheck(args...)
   576  	if err != nil {
   577  		return 0, err
   578  	}
   579  	sigStr, typArg, valArg := ParseArguments(types, "I", args...)
   580  	defer FreeArgs(len(args), types, typArg, valArg)
   581  	cmn, csig := ParseNameSig(methodName, sigStr)
   582  	defer FreeNameSig(cmn, csig)
   583  	clen := C.int(len(args))
   584  	ret := C.callDoubleMethod(o.env, o.clazz, o.obj, cmn, csig, clen, typArg, valArg)
   585  	return float64(ret), nil
   586  }
   587  
   588  func (o *JavaObject) InvokeBoolean(methodName string, args ...any) (bool, error) {
   589  	types, err := ArgumentsCheck(args...)
   590  	if err != nil {
   591  		return false, err
   592  	}
   593  	sigStr, typArg, valArg := ParseArguments(types, "I", args...)
   594  	defer FreeArgs(len(args), types, typArg, valArg)
   595  	cmn, csig := ParseNameSig(methodName, sigStr)
   596  	defer FreeNameSig(cmn, csig)
   597  	clen := C.int(len(args))
   598  	ret := C.callBooleanMethod(o.env, o.clazz, o.obj, cmn, csig, clen, typArg, valArg)
   599  	return int(ret) != 0, nil
   600  }
   601  
   602  func (o *JavaObject) GetObject(fieldName string, className string) *JavaObject {
   603  	sig := strings.ReplaceAll(className, ".", "/")
   604  	cmn, csig := ParseNameSig(fieldName, "L"+sig+";")
   605  	defer FreeNameSig(cmn, csig)
   606  	ret := C.getObjectObject(o.env, o.clazz, o.obj, cmn, csig)
   607  	if ret == C.jobject(C.NULL) {
   608  		return nil
   609  	}
   610  	return &JavaObject{
   611  		jvm:       o.jvm,
   612  		env:       o.env,
   613  		clazz:     C.findClass(o.env, csig),
   614  		obj:       ret,
   615  		ClassName: className,
   616  	}
   617  }
   618  
   619  func (o *JavaObject) SetObject(fieldName string, className string, obj *JavaObject) {
   620  	sig := strings.ReplaceAll(className, ".", "/")
   621  	cmn, csig := ParseNameSig(fieldName, "L"+sig+";")
   622  	defer FreeNameSig(cmn, csig)
   623  	C.setObjectObject(o.env, o.clazz, o.obj, cmn, csig, obj.obj)
   624  }
   625  
   626  func (o *JavaObject) GetString(fieldName string) string {
   627  	cmn := C.CString(fieldName)
   628  	defer C.free(unsafe.Pointer(cmn))
   629  	ret := C.getObjectString(o.env, o.clazz, o.obj, cmn)
   630  	if ret == nil {
   631  		return ""
   632  	}
   633  	defer C.free(unsafe.Pointer(ret))
   634  	return C.GoString(ret)
   635  }
   636  
   637  func (o *JavaObject) SetString(fieleName string, value string) {
   638  	cmn := C.CString(fieleName)
   639  	defer C.free(unsafe.Pointer(cmn))
   640  	cval := C.CString(value)
   641  	defer C.free(unsafe.Pointer(cval))
   642  	C.setObjectString(o.env, o.clazz, o.obj, cmn, cval)
   643  }
   644  
   645  func (o *JavaObject) GetInt(fieldName string) int {
   646  	cmn := C.CString(fieldName)
   647  	defer C.free(unsafe.Pointer(cmn))
   648  	ret := C.getObjectInt(o.env, o.clazz, o.obj, cmn)
   649  	return int(ret)
   650  }
   651  
   652  func (o *JavaObject) SetInt(fieldName string, value int) {
   653  	cmn := C.CString(fieldName)
   654  	defer C.free(unsafe.Pointer(cmn))
   655  	C.setObjectInt(o.env, o.clazz, o.obj, cmn, C.int(value))
   656  }
   657  
   658  func (o *JavaObject) GetLong(fieldName string) int64 {
   659  	cmn := C.CString(fieldName)
   660  	defer C.free(unsafe.Pointer(cmn))
   661  	ret := C.getObjectLong(o.env, o.clazz, o.obj, cmn)
   662  	return int64(ret)
   663  }
   664  
   665  func (o *JavaObject) SetLong(fieldName string, value int64) {
   666  	cmn := C.CString(fieldName)
   667  	defer C.free(unsafe.Pointer(cmn))
   668  	C.setObjectLong(o.env, o.clazz, o.obj, cmn, C.long(value))
   669  }
   670  
   671  func (o *JavaObject) GetShort(fieldName string) int16 {
   672  	cmn := C.CString(fieldName)
   673  	defer C.free(unsafe.Pointer(cmn))
   674  	ret := C.getObjectShort(o.env, o.clazz, o.obj, cmn)
   675  	return int16(ret)
   676  }
   677  
   678  func (o *JavaObject) SetShort(fieldName string, value int16) {
   679  	cmn := C.CString(fieldName)
   680  	defer C.free(unsafe.Pointer(cmn))
   681  	C.setObjectShort(o.env, o.clazz, o.obj, cmn, C.short(value))
   682  }
   683  
   684  func (o *JavaObject) GetByte(fieldName string) uint8 {
   685  	cmn := C.CString(fieldName)
   686  	defer C.free(unsafe.Pointer(cmn))
   687  	ret := C.getObjectByte(o.env, o.clazz, o.obj, cmn)
   688  	return uint8(ret)
   689  }
   690  
   691  func (o *JavaObject) SetByte(fieldName string, value uint8) {
   692  	cmn := C.CString(fieldName)
   693  	defer C.free(unsafe.Pointer(cmn))
   694  	C.setObjectByte(o.env, o.clazz, o.obj, cmn, C.uchar(value))
   695  }
   696  
   697  func (o *JavaObject) GetFloat(fieldName string) float32 {
   698  	cmn := C.CString(fieldName)
   699  	defer C.free(unsafe.Pointer(cmn))
   700  	ret := C.getObjectFloat(o.env, o.clazz, o.obj, cmn)
   701  	return float32(ret)
   702  }
   703  
   704  func (o *JavaObject) SetFloat(fieldName string, value float32) {
   705  	cmn := C.CString(fieldName)
   706  	defer C.free(unsafe.Pointer(cmn))
   707  	C.setObjectFloat(o.env, o.clazz, o.obj, cmn, C.float(value))
   708  }
   709  
   710  func (o *JavaObject) GetDouble(fieldName string) float64 {
   711  	cmn := C.CString(fieldName)
   712  	defer C.free(unsafe.Pointer(cmn))
   713  	ret := C.getObjectDouble(o.env, o.clazz, o.obj, cmn)
   714  	return float64(ret)
   715  }
   716  
   717  func (o *JavaObject) SetDouble(fieldName string, value float64) {
   718  	cmn := C.CString(fieldName)
   719  	defer C.free(unsafe.Pointer(cmn))
   720  	C.setObjectDouble(o.env, o.clazz, o.obj, cmn, C.double(value))
   721  }
   722  
   723  func (o *JavaObject) GetBoolean(fieldName string) bool {
   724  	cmn := C.CString(fieldName)
   725  	defer C.free(unsafe.Pointer(cmn))
   726  	ret := C.getObjectBoolean(o.env, o.clazz, o.obj, cmn)
   727  	return ret != 0
   728  }
   729  
   730  func (o *JavaObject) SetBoolean(fieldName string, value bool) {
   731  	cmn := C.CString(fieldName)
   732  	defer C.free(unsafe.Pointer(cmn))
   733  	var b C.int
   734  	if value {
   735  		b = 1
   736  	} else {
   737  		b = 0
   738  	}
   739  	C.setObjectBoolean(o.env, o.clazz, o.obj, cmn, b)
   740  }