如何通过JNI从C ++正确发送std :: map <>到Java?

时间:2018-07-21 21:41:27

标签: java android c++ java-native-interface

我正在尝试通过JNI从C ++向我的Java应用程序发送一个std :: map <>。我已经掌握了可通过JNI进行操作的基本知识,例如字符串和整数,但是我无法使地图通过。我已经进行了研究,发现需要将其转换为jobject HashMap。我在任何地方都找不到完整的答案,因此我不得不拼凑出不同答案的某些部分,而无法正常工作。

在C ++方面:

void AppAnalytics::sendCustomAction(std::string name, std::map<std::string, std::string> strings, std::map<std::string, int> ints) {

cocos2d::JniMethodInfo methodInfo;

if (! getJNIStaticMethodInfo(methodInfo, "sendCustomAction", "(Ljava/lang/String;java/util/HashMap;java/util/HashMap;)V")) {
    return;
}

jclass clazz = methodInfo.env->FindClass("java/util/HashMap");
jmethodID init = methodInfo.env->GetMethodID(clazz, "<init>", "()V");
jobject stringMap = methodInfo.env->NewObject(clazz, init);

jmethodID putMethod = methodInfo.env->GetMethodID(
                                       clazz,
                                       "put",
                                                  "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"
                                       );

map<std::string, std::string>::iterator itStr;
for ( itStr = strings.begin(); itStr != strings.end(); itStr++ ) {
    const char * firstStr = itStr->first.c_str();
    const char * secondStr = itStr->second.c_str();

    jstring key = methodInfo.env->NewStringUTF( firstStr );
    jstring value = methodInfo.env->NewStringUTF( secondStr );

    methodInfo.env->CallObjectMethod(
                                     stringMap,
                                     putMethod,
                                     key,
                                     value
                                     );
}

jobject intMap = methodInfo.env->NewObject(clazz, init);


map<std::string, int>::iterator itInt;
for ( itInt = ints.begin(); itInt != ints.end(); itInt++ ) {
    const char * firstStr = itInt->first.c_str();

    jstring key = methodInfo.env->NewStringUTF( firstStr );
    int value = itInt->second;

    methodInfo.env->CallVoidMethod(
                                     intMap,
                                     putMethod,
                                     key,
                                     value
                                     );
}

jstring stringArg = methodInfo.env->NewStringUTF(name.c_str());
methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, stringArg, stringMap, intMap);
methodInfo.env->DeleteLocalRef(stringArg);
methodInfo.env->DeleteLocalRef(stringMap);
methodInfo.env->DeleteLocalRef(intMap);
methodInfo.env->DeleteLocalRef(methodInfo.classID);
}

这是Java应用程序的接收方:

public class AnalyticsHelper {

public static void sendCustomAction(String name, HashMap<String, String> strings, HashMap<String, Integer> ints) {
    CustomEvent event = new CustomEvent(name);

    for (String key : strings.keySet()) {
        event.putCustomAttribute(key, strings.get(key));
    }
    for (String key : ints.keySet()) {
        event.putCustomAttribute(key, ints.get(key));
    }

    Answers.getInstance().logCustom(event);
}

}

从应用程序内部触发操作时,我总是在Java端收到此错误:

E / JniHelper:无法找到sendCustomAction的静态方法ID

任何帮助将不胜感激。我已经尝试过将自己拥有的东西进行不同的组合,但是似乎永远无法得到。

谢谢!

0 个答案:

没有答案