1. 程式人生 > >jni程式設計中NewStringUTF報錯

jni程式設計中NewStringUTF報錯

解決方法:換用NewByteArray,然後再將jbyteArray轉換成jstring

stackoverflow上有一篇關於這個問題不錯的回答:點選連結

We found a solution by sending the contents of the std::string in
jbyte array and let the java side be java and return the jstring we
could use on the C++ jni side. For us these strings are coming from
the users keyboard and I have 170k crashes in one week that says they
use emoji in character names and chat like crazy… and naming their
avatars in itself caused crashes too. So any lobby a Android 5.x user
joined would cause them to crash as soon as their client tried to
render the other players names with the characters in question. In
Android 4.x this was not an issue in that it just printed some garbage
characters. In your c++ side you can do something like this to achieve
this function:

jstring JniHelper::getjString(const char *input) {
    JniMethodInfo minfo; // JniHelper

    bool hasMethod = JniHelper::getStaticMethodInfo (minfo, APPTAG_JNI_PACKAGE_NAME, "convertCStringToJniSafeString", "([B)Ljava/lang/String;");
    if (!hasMethod)
    {
        return minfo.env->NewStringUTF(""
); // TODO Tune your response to fit your needs... } else { string nativeString = std::string(input); // has a bit of a code smell, there is probably a better way. // cite: http://stackoverflow.com/questions/27303316/c-stdstring-to-jstring-with-a-fixed-length jbyteArray array
= minfo.env->NewByteArray(nativeString.length()); minfo.env->SetByteArrayRegion(array,0,nativeString.length(),(jbyte*)nativeString.c_str()); // cite: http://discuss.cocos2d-x.org/t/jni-return-string/9982/3 jstring str = (jstring)minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID, array); minfo.env->DeleteLocalRef(array); return str; } }

On the java side turn that into a java string and return it in the
same method:

public static String convertCStringToJniSafeString(byte[] input) {
    try {
        String nativeString = new String(input, "UTF-8"); // please debate what the safest charset should be?
        return nativeString;
    } catch (UnsupportedEncodingException e) {
        // TODO Simplistic Error handling, tune to your needs.
        Log.e(APPTAG, "Couldn't convert the jbyteArray to jstring");
        return ""; //JSTRING_CONVERT_FAIL
    }
}

但是JniMethodInfo是Cocos2d-x的資料型別,對於一般的jni程式設計

jbyteArray byteArray=env->NewByteArray(result_len);
    env->SetByteArrayRegion(byteArray,0,result_len, reinterpret_cast<const jbyte*>(json_info.c_str()));
    jclass MyClass = env->FindClass((const char*)"java/lang/String");
    if(MyClass)
    {
        jmethodID mid=env->GetStaticMethodID(MyClass,"byte2Str","([B)Ljava/lang/String;");
        if(mid)
        {
            jstring jstring1=(jstring)env->CallStaticObjectMethod(MyClass,mid,byteArray);
            env->DeleteLocalRef(byteArray);
            return jstring1;
        }
    }