From b380472956a0a3b6d927b1ccc5d6bae94cd0d1af Mon Sep 17 00:00:00 2001 From: Chris Waldon Date: Sat, 20 Jun 2020 11:27:23 -0400 Subject: [PATCH] feat: enable looking up values of static fields --- gojni.h | 10 ++++++ jni.c | 41 ++++++++++++++++++++++ jni.go | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+) diff --git a/gojni.h b/gojni.h index 6895305..66dbf6b 100644 --- a/gojni.h +++ b/gojni.h @@ -7,6 +7,7 @@ __attribute__ ((visibility ("hidden"))) void _jni_ExceptionClear(JNIEnv *env); __attribute__ ((visibility ("hidden"))) jclass _jni_GetObjectClass(JNIEnv *env, jobject obj); __attribute__ ((visibility ("hidden"))) jmethodID _jni_GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig); __attribute__ ((visibility ("hidden"))) jmethodID _jni_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig); +__attribute__ ((visibility ("hidden"))) jfieldID _jni_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig); __attribute__ ((visibility ("hidden"))) jsize _jni_GetStringLength(JNIEnv *env, jstring str); __attribute__ ((visibility ("hidden"))) const jchar *_jni_GetStringChars(JNIEnv *env, jstring str); __attribute__ ((visibility ("hidden"))) jstring _jni_NewString(JNIEnv *env, const jchar *unicodeChars, jsize len); @@ -23,3 +24,12 @@ __attribute__ ((visibility ("hidden"))) jbyteArray _jni_NewByteArray(JNIEnv *env __attribute__ ((visibility ("hidden"))) jbyte *_jni_GetByteArrayElements(JNIEnv *env, jbyteArray arr); __attribute__ ((visibility ("hidden"))) void _jni_ReleaseByteArrayElements(JNIEnv *env, jbyteArray arr, jbyte *elems, jint mode); __attribute__ ((visibility ("hidden"))) jsize _jni_GetArrayLength(JNIEnv *env, jarray arr); +__attribute__ ((visibility ("hidden"))) jobject _jni_GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID); +__attribute__ ((visibility ("hidden"))) jboolean _jni_GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID); +__attribute__ ((visibility ("hidden"))) jbyte _jni_GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID); +__attribute__ ((visibility ("hidden"))) jchar _jni_GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID); +__attribute__ ((visibility ("hidden"))) jshort _jni_GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID); +__attribute__ ((visibility ("hidden"))) jint _jni_GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID); +__attribute__ ((visibility ("hidden"))) jlong _jni_GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID); +__attribute__ ((visibility ("hidden"))) jfloat _jni_GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID); +__attribute__ ((visibility ("hidden"))) jdouble _jni_GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID); diff --git a/jni.c b/jni.c index 45b1d27..84c743a 100644 --- a/jni.c +++ b/jni.c @@ -36,6 +36,10 @@ jmethodID _jni_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, co return (*env)->GetStaticMethodID(env, clazz, name, sig); } +jfieldID _jni_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig) { + return (*env)->GetStaticFieldID(env, clazz, name, sig); +} + jsize _jni_GetStringLength(JNIEnv *env, jstring str) { return (*env)->GetStringLength(env, str); } @@ -99,3 +103,40 @@ void _jni_ReleaseByteArrayElements(JNIEnv *env, jbyteArray arr, jbyte *elems, ji jsize _jni_GetArrayLength(JNIEnv *env, jarray arr) { return (*env)->GetArrayLength(env, arr); } + +jobject _jni_GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID) { + return (*env)->GetStaticObjectField(env, clazz, fieldID); +} + +jboolean _jni_GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID) { + return (*env)->GetStaticBooleanField(env, clazz, fieldID); +} + +jbyte _jni_GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID) { + return (*env)->GetStaticByteField(env, clazz, fieldID); +} + +jchar _jni_GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID) { + return (*env)->GetStaticCharField(env, clazz, fieldID); +} + +jshort _jni_GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID) { + return (*env)->GetStaticShortField(env, clazz, fieldID); +} + +jint _jni_GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID) { + return (*env)->GetStaticIntField(env, clazz, fieldID); +} + +jlong _jni_GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID) { + return (*env)->GetStaticLongField(env, clazz, fieldID); +} + +jfloat _jni_GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID) { + return (*env)->GetStaticFloatField(env, clazz, fieldID); +} + +jdouble _jni_GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID) { + return (*env)->GetStaticDoubleField(env, clazz, fieldID); +} + diff --git a/jni.go b/jni.go index b3485d7..8cc7eee 100644 --- a/jni.go +++ b/jni.go @@ -38,6 +38,7 @@ type ( Class C.jclass Object C.jobject MethodID C.jmethodID + FieldID C.jfieldID String C.jstring ByteArray C.jbyteArray Value uint64 // All JNI types fit into 64-bits. @@ -212,6 +213,20 @@ func GetStaticMethodID(e Env, cls Class, name, signature string) MethodID { return MethodID(m) } +// GetStaticFieldID returns the id for a static field. It panics if the field +// wasn't found. +func GetStaticFieldID(e Env, cls Class, name, signature string) FieldID { + mname := C.CString(name) + defer C.free(unsafe.Pointer(mname)) + msig := C.CString(signature) + defer C.free(unsafe.Pointer(msig)) + m := C._jni_GetStaticFieldID(e.env, C.jclass(cls), mname, msig) + if err := exception(e); err != nil { + panic(err) + } + return FieldID(m) +} + // GetMethodID returns the id for a method. It panics if the method // wasn't found. func GetMethodID(e Env, cls Class, name, signature string) MethodID { @@ -259,3 +274,93 @@ func GoString(e Env, str String) string { utf8 := utf16.Decode(utf16Chars) return string(utf8) } + +// GetStaticObjectField looks up the value of a static field of type Object. +// It panics if it is unable to find the field. +func GetStaticObjectField(env Env, clazz Class, fieldID FieldID) Object { + value := C._jni_GetStaticObjectField(env.env, C.jclass(clazz), C.jfieldID(fieldID)) + if err := exception(env); err != nil { + panic(err) + } + return Object(value) +} + +// GetStaticBooleanField looks up the value of a static field of type boolean. +// It panics if it is unable to find the field. +func GetStaticBooleanField(env Env, clazz Class, fieldID FieldID) bool { + value := C._jni_GetStaticBooleanField(env.env, C.jclass(clazz), C.jfieldID(fieldID)) + if err := exception(env); err != nil { + panic(err) + } + return value != 0 +} + +// GetStaticByteField looks up the value of a static field of type byte. +// It panics if it is unable to find the field. +func GetStaticByteField(env Env, clazz Class, fieldID FieldID) byte { + value := C._jni_GetStaticByteField(env.env, C.jclass(clazz), C.jfieldID(fieldID)) + if err := exception(env); err != nil { + panic(err) + } + return byte(value) +} + +// GetStaticCharField looks up the value of a static field of type char. +// It panics if it is unable to find the field. +func GetStaticCharField(env Env, clazz Class, fieldID FieldID) byte { + value := C._jni_GetStaticCharField(env.env, C.jclass(clazz), C.jfieldID(fieldID)) + if err := exception(env); err != nil { + panic(err) + } + return byte(value) +} + +// GetStaticShortField looks up the value of a static field of type short. +// It panics if it is unable to find the field. +func GetStaticShortField(env Env, clazz Class, fieldID FieldID) int16 { + value := C._jni_GetStaticShortField(env.env, C.jclass(clazz), C.jfieldID(fieldID)) + if err := exception(env); err != nil { + panic(err) + } + return int16(value) +} + +// GetStaticIntField looks up the value of a static field of type int. +// It panics if it is unable to find the field. +func GetStaticIntField(env Env, clazz Class, fieldID FieldID) int32 { + value := C._jni_GetStaticIntField(env.env, C.jclass(clazz), C.jfieldID(fieldID)) + if err := exception(env); err != nil { + panic(err) + } + return int32(value) +} + +// GetStaticLongField looks up the value of a static field of type long. +// It panics if it is unable to find the field. +func GetStaticLongField(env Env, clazz Class, fieldID FieldID) int64 { + value := C._jni_GetStaticLongField(env.env, C.jclass(clazz), C.jfieldID(fieldID)) + if err := exception(env); err != nil { + panic(err) + } + return int64(value) +} + +// GetStaticFloatField looks up the value of a static field of type float. +// It panics if it is unable to find the field. +func GetStaticFloatField(env Env, clazz Class, fieldID FieldID) float32 { + value := C._jni_GetStaticFloatField(env.env, C.jclass(clazz), C.jfieldID(fieldID)) + if err := exception(env); err != nil { + panic(err) + } + return float32(value) +} + +// GetStaticDoubleField looks up the value of a static field of type double. +// It panics if it is unable to find the field. +func GetStaticDoubleField(env Env, clazz Class, fieldID FieldID) float64 { + value := C._jni_GetStaticDoubleField(env.env, C.jclass(clazz), C.jfieldID(fieldID)) + if err := exception(env); err != nil { + panic(err) + } + return float64(value) +}