-
-
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