C++ returning HashMap<string, boolean> object to Java

匿名 (未验证) 提交于 2019-12-03 01:34:02

问题:

I have a JNI function that JAVA calls that needs to build and return a HashMap. The key for the map is 'String' and the respective value is 'boolean' or 'Boolean' (either one is fine, as long as it works). With the current code that I have (below), the string is successfully added to the map that is returned and can be accessed in Java. However, when trying to access the value in JAVA, it comes up null.

jclass mapclass = env->FindClass("java/util/HashMap"); jmethodID initmeth = env->GetMethodID(mapclass, "<init>", "()V"); jmethodID putmeth = env->GetMethodID(mapclass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); jobject roster_return = env->NewObject(mapclass, initmeth);  int roster_map_size; std::map<std::string, RosterItem>* roster_map = GetRosterMap(); std::map<std::string, RosterItem>::iterator iter; if (!roster_map || roster_map->size() < 1)     return roster_return;  iter = roster_map->begin(); while (iter != roster_map->end()) {     env->CallObjectMethod(roster_return, putmeth, env->NewStringUTF(iter->second.name.c_str()), (jboolean)iter->second.isfriend);     iter++; } 

I've tried generating a Boolean object, but I cannot seem to figure out how to create a new one. I've tried the following code, but it errors on the "GetMethodID" for the boolean "init".

jclass mapclass = env->FindClass("java/util/HashMap"); jclass boolclass = env->FindClass("java/lang/Boolean"); jmethodID initmeth = env->GetMethodID(mapclass, "<init>", "()V"); //-----------------It errors on the next line----------------------- jmethodID initbool = env->GetMethodID(boolclass, "<init>", "()V"); jmethodID putmeth = env->GetMethodID(mapclass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); jobject roster_return = env->NewObject(mapclass, initmeth);  int roster_map_size; std::map<std::string, RosterItem>* roster_map = GetRosterMap();; std::map<std::string, RosterItem>::iterator iter; if (!roster_map || roster_map->size() < 1)     return roster_return;  iter = roster_map->begin(); while (iter != roster_map->end()) {     LOGE("adding contact: %s", iter->second.jid.Str().c_str());  //---Not sure what to pass in the next function here for the fourth argument---      env->CallObjectMethod(roster_return, putmeth, env->NewStringUTF(iter->second.name.c_str()), (jboolean)iter->second.isfriend);     iter++; } 

回答1:

Old question, but I was searching for this today as well. When you're bouncing around between languages it's easy to forget that there's a difference between Java's primitive boolean type vs the nullable Boolean Object type. A Map's value has to be an Object, thus Boolean is needed.

So, to create a new Boolean object:

// Sample C++ boolean variable you want to convert to Java: bool someBoolValue = true;  // Get the Boolean class jclass boolClass = env->FindClass("java/lang/Boolean"); // Find the constructor that takes a boolean (note not Boolean) parameter: jmethodID boolInitMethod = env->GetMethodID(boolClass, "<init>", "(Z)V");  // Create the object jobject boolObj = env->NewObject(boolClass,                                  boolInitMethod,                                  someBoolValue ? JNI_TRUE : JNI_FALSE); 


回答2:

Maybe it is easier if you define in Java the static functions createMap() and addToMap(String, boolean) and simply call them from JNI as needed, instead of going through all the mess of getting the correct classes and fields only in JNI.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!