JNI: HashMap<->unordered_map
Contents
前言
在进行 JNI 开发的时候,经常会碰到需要传递 Map 的需求。
它们实现起来不难,但是写起来还是比较麻烦的,每次要写的时候都要老半天。
所以这里给一个参考,希望在用到的时候能帮你进行快速开发。
HashMap -> unordered_map
std::unique_ptr<std::unordered_map<std::string, std::string>>
hashMap2unordered_map(JNIEnv *env, jobject data) {
std::unique_ptr<std::unordered_map<std::string, std::string>> map = std::make_unique<std::unordered_map<std::string, std::string>>();
if (!env->IsSameObject(data, nullptr)) {
jclass mapClass = env->FindClass("java/util/Map");
jmethodID entrySetMethod = env->GetMethodID(mapClass, "entrySet", "()Ljava/util/Set;");
jobject entries = env->CallObjectMethod(data, entrySetMethod);
jclass setClass = env->FindClass("java/util/Set");
jmethodID iteratorMethod = env->GetMethodID(setClass, "iterator", "()Ljava/util/Iterator;");
jclass iterClass = env->FindClass("java/util/Iterator");
jmethodID hasNextMethod = env->GetMethodID(iterClass, "hasNext", "()Z");
jmethodID nextMethod = env->GetMethodID(iterClass, "next", "()Ljava/lang/Object;");;
jclass entryClass = env->FindClass("java/util/Map$Entry");
jmethodID getKeyMethod = env->GetMethodID(entryClass, "getKey", "()Ljava/lang/Object;");
jmethodID getValueMethod = env->GetMethodID(entryClass, "getValue", "()Ljava/lang/Object;");
jobject iterator = env->CallObjectMethod(entries, iteratorMethod);
while (env->CallBooleanMethod(iterator, hasNextMethod)) {
jobject entry = env->CallObjectMethod(iterator, nextMethod);
jstring jKey = static_cast<jstring>(env->CallObjectMethod(entry,
getKeyMethod));
std::string key;
if (!env->IsSameObject(jKey, nullptr)) {
const char *keyStr = env->GetStringUTFChars(jKey, nullptr);
key.append(keyStr);
env->ReleaseStringUTFChars(jKey, keyStr);
}
jstring jValue = static_cast<jstring>(env->CallObjectMethod(entry,
getValueMethod));
std::string value;
if (!env->IsSameObject(jValue, nullptr)) {
const char *valueStr = env->GetStringUTFChars(jValue, nullptr);
value.append(valueStr);
env->ReleaseStringUTFChars(jValue, valueStr);
}
map->emplace(std::move(key), std::move(value));
env->DeleteLocalRef(jValue);
env->DeleteLocalRef(jKey);
env->DeleteLocalRef(entry);
}
env->DeleteLocalRef(iterator);
env->DeleteLocalRef(entryClass);
env->DeleteLocalRef(iterClass);
env->DeleteLocalRef(setClass);
env->DeleteLocalRef(mapClass);
}
return map;
}
unordered_map -> HashMap
jobject unordered_map2HashMap(JNIEnv *env,
std::unique_ptr<std::unordered_map<std::string, std::string>> params) {
jobject map = nullptr;
if (params) {
jclass mapClass = env->FindClass("java/util/HashMap");
jmethodID initMethod = env->GetMethodID(mapClass, "<init>", "()V");
jmethodID putMethod = env->GetMethodID(mapClass, "put",
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
map = env->NewObject(mapClass, initMethod);
for (auto &item: *params) {
jstring key = env->NewStringUTF(item.first.c_str());
jstring value = env->NewStringUTF(item.second.c_str());
env->CallObjectMethod(map, putMethod, key, value);
env->DeleteLocalRef(value);
env->DeleteLocalRef(key);
}
env->DeleteLocalRef(mapClass);
}
return map;
}