-
-
Save qh-huang/6e43fb2311ee3c31752e11a4415deeb1 to your computer and use it in GitHub Desktop.
| // ==================== pull from Facebook/rockdb@github ==================== | |
| class ListJni { | |
| public: | |
| // Get the java class id of java.util.List. | |
| static jclass getListClass(JNIEnv* env) { | |
| jclass jclazz = env->FindClass("java/util/List"); | |
| assert(jclazz != nullptr); | |
| return jclazz; | |
| } | |
| // Get the java class id of java.util.ArrayList. | |
| static jclass getArrayListClass(JNIEnv* env) { | |
| jclass jclazz = env->FindClass("java/util/ArrayList"); | |
| assert(jclazz != nullptr); | |
| return jclazz; | |
| } | |
| // Get the java class id of java.util.Iterator. | |
| static jclass getIteratorClass(JNIEnv* env) { | |
| jclass jclazz = env->FindClass("java/util/Iterator"); | |
| assert(jclazz != nullptr); | |
| return jclazz; | |
| } | |
| // Get the java method id of java.util.List.iterator(). | |
| static jmethodID getIteratorMethod(JNIEnv* env) { | |
| static jmethodID mid = env->GetMethodID( | |
| getListClass(env), "iterator", "()Ljava/util/Iterator;"); | |
| assert(mid != nullptr); | |
| return mid; | |
| } | |
| // Get the java method id of java.util.Iterator.hasNext(). | |
| static jmethodID getHasNextMethod(JNIEnv* env) { | |
| static jmethodID mid = env->GetMethodID( | |
| getIteratorClass(env), "hasNext", "()Z"); | |
| assert(mid != nullptr); | |
| return mid; | |
| } | |
| // Get the java method id of java.util.Iterator.next(). | |
| static jmethodID getNextMethod(JNIEnv* env) { | |
| static jmethodID mid = env->GetMethodID( | |
| getIteratorClass(env), "next", "()Ljava/lang/Object;"); | |
| assert(mid != nullptr); | |
| return mid; | |
| } | |
| // Get the java method id of arrayList constructor. | |
| static jmethodID getArrayListConstructorMethodId(JNIEnv* env, jclass jclazz) { | |
| static jmethodID mid = env->GetMethodID( | |
| jclazz, "<init>", "(I)V"); | |
| assert(mid != nullptr); | |
| return mid; | |
| } | |
| // Get the java method id of java.util.List.add(). | |
| static jmethodID getListAddMethodId(JNIEnv* env) { | |
| static jmethodID mid = env->GetMethodID( | |
| getListClass(env), "add", "(Ljava/lang/Object;)Z"); | |
| assert(mid != nullptr); | |
| return mid; | |
| } | |
| }; | |
| class ByteJni { | |
| public: | |
| // Get the java class id of java.lang.Byte. | |
| static jclass getByteClass(JNIEnv* env) { | |
| jclass jclazz = env->FindClass("java/lang/Byte"); | |
| assert(jclazz != nullptr); | |
| return jclazz; | |
| } | |
| // Get the java method id of java.lang.Byte.byteValue. | |
| static jmethodID getByteValueMethod(JNIEnv* env) { | |
| static jmethodID mid = env->GetMethodID( | |
| getByteClass(env), "byteValue", "()B"); | |
| assert(mid != nullptr); | |
| return mid; | |
| } | |
| }; | |
| // ==================== Java ArrayList<String> ==> C++ vector<string> ==================== | |
| static jclass java_util_ArrayList; | |
| static jmethodID java_util_ArrayList_; | |
| jmethodID java_util_ArrayList_size; | |
| jmethodID java_util_ArrayList_get; | |
| jmethodID java_util_ArrayList_add; | |
| static thread_local JNIEnv* env; | |
| void init() { | |
| java_util_ArrayList = static_cast<jclass>(env->NewGlobalRef(env->FindClass("java/util/ArrayList"))); | |
| java_util_ArrayList_ = env->GetMethodID(java_util_ArrayList, "<init>", "(I)V"); | |
| java_util_ArrayList_size = env->GetMethodID (java_util_ArrayList, "size", "()I"); | |
| java_util_ArrayList_get = env->GetMethodID(java_util_ArrayList, "get", "(I)Ljava/lang/Object;"); | |
| java_util_ArrayList_add = env->GetMethodID(java_util_ArrayList, "add", "(Ljava/lang/Object;)Z"); | |
| } | |
| std::vector<std::string> java2cpp(jobject arrayList) { | |
| jint len = env->CallIntMethod(arrayList, java_util_ArrayList_size); | |
| std::vector<std::string> result; | |
| result.reserve(len); | |
| for (jint i=0; i<len; i++) { | |
| jstring element = static_cast<jstring>(env->CallObjectMethod(arrayList, java_util_ArrayList_get, i)); | |
| const char* pchars = env->GetStringUTFChars(element, nullptr); | |
| result.emplace_back(pchars); | |
| env->ReleaseStringUTFChars(element, pchars); | |
| env->DeleteLocalRef(element); | |
| } | |
| } | |
| // ==================== C++ vector<string> ==> Java ArrayList<String> ==================== | |
| jobject cpp2java(std::vector<std::string> vector) { | |
| jobject result = env->NewObject(java_util_ArrayList, java_util_ArrayList_, vector.size()); | |
| for (std::string s: vector) { | |
| jstring element = env->NewStringUTF(s.c_str()); | |
| env->CallBooleanMethod(result, java_util_ArrayList_add, element); | |
| env->DeleteLocalRef(element); | |
| } | |
| return result; | |
| } |
For anyone who intends to use jobject cpp2java(std::vector<std::string> vector), the JVM will crash because java_util_ArrayList_add seems to have a typo. It should have a Z and not a V.
java_util_ArrayList_add = env->GetMethodID(java_util_ArrayList, "add", "(Ljava/lang/Object;)V");
Becomes
java_util_ArrayList_add = env->GetMethodID(java_util_ArrayList, "add", "(Ljava/lang/Object;)Z");
And one more thing, although it works fine after that, java.util.ArrayList#add(E) returns a boolean. You might want to change
env->CallVoidMethod(result, java_util_ArrayList_add, element);
to
env->CallBooleanMethod(result, java_util_ArrayList_add, element);.
Hi, I used your code. the return statement of java2cpp() was omitted. Anyway, thank you very for this clean and easy to follow jni codes. :)
@yuvarajselvaraj, sorry for this late reply after 1 year..., unfortunately, I don't see any relationship between JNI and JSON object.
@IncPlusPlus, I just updated the gist accordingly, thank you so much!
@jachimsevero, thanks for notifying me. However, I can't reproduce the issue which you described; on the other hand, this gist is not actively maintained and maybe you will get some insight from the original code where I pull from before: https://github.com/facebook/rocksdb/blob/master/java/rocksjni/portal.h
can i parse a jsonobject and get its value by key-jni