Android ICS 4.0 NDK NewStringUTF is crashing down the App

前端 未结 10 1945
长情又很酷
长情又很酷 2020-12-02 15:01

I have a method in JNI C/C++ which takes jstring and returns back jstring some thing like as below,

  NATIVE_CALL(jstring, method)(JNIEnv * env, jobject obj         


        
相关标签:
10条回答
  • 2020-12-02 15:34

    For me, the solution was to place the content on a const char*:

    const char* string = name_sin.c_str();
    jstring utf8 = env_r->NewStringUTF(string);
    

    and the function:

    jclass cls_Env = env_r->FindClass(CLASS_ACTIVITY_NAME); 
    jmethodID mid = env_r->GetMethodID(cls_Env, "Delegate",
                                     "(Ljava/lang/String;)V");
    
    
    //todo importante hacerlo asi, si pasas directamente c_str a veces da error de carater no UTF 8
    const char* string = name_sin.c_str();
    jstring utf8 = env_r->NewStringUTF(string);
    
    env_r->CallVoidMethod(*object_r, mid, utf8);
    
    env_r->DeleteLocalRef(utf8);
    
    0 讨论(0)
  • 2020-12-02 15:35

    This works for me in c++

    extern "C" JNIEXPORT
    jstring Java_com_example_ndktest_MainActivity_TalkToJNI(JNIEnv* env, jobject javaThis, jstring strFromJava)
    {
        jboolean isCopy;
        const char* szHTML = env->GetStringUTFChars(strFromJava, &isCopy);
    
        std::string strMine;
        strMine = szHTML;
        strMine += " --- Hello from the JNI!!";
    
        env->ReleaseStringUTFChars(strFromJava, szHTML);
        return env->NewStringUTF(strMine.c_str());
    }
    
    0 讨论(0)
  • 2020-12-02 15:42

    This is how I done this.

    1- Char Array to JByteArray.

    2- JByteArray to JString.

    3- Return jstring to java side.

    JNI Code; (.c) format

    jstring Java_com_x_y_z_methodName(JNIEnv *env, jobject thiz) {
        int size = 16;
        char r[] = {'P', 'K', 'd', 'h', 't', 'X', 'M', 'm', 'r', '1', '8', 'n', '2', 'L', '9', 'K'};
        jbyteArray array = (*env)->NewByteArray(env, size);
        (*env)->SetByteArrayRegion(env, array, 0, size, r);
        jstring strEncode = (*env)->NewStringUTF(env, "UTF-8");
        jclass cls = (*env)->FindClass(env, "java/lang/String");
        jmethodID ctor = (*env)->GetMethodID(env, cls, "<init>", "([BLjava/lang/String;)V");
        jstring object = (jstring) (*env)->NewObject(env, cls, ctor, array, strEncode);
    
        return object;
    }
    

    Java Code;

    native String methodName();
    

    Other Approach Not Works For Me;

    I also tried return (*env)->NewStringUTF(env, r) but returns some characters that are not in the char array, at the end of the string where with the warning of JNI WARNING: input is not valid Modified UTF-8: illegal continuation byte 0x40.

    Example; PKdhtXMmr18n2L9K�ؾ�����-DL

    Edit:

    C++ version

    jstring clientStringFromStdString(JNIEnv *env,const std::string &str){
    //    return env->NewStringUTF(str.c_str());
        jbyteArray array = env->NewByteArray(str.size());
        env->SetByteArrayRegion(array, 0, str.size(), (const jbyte*)str.c_str());
        jstring strEncode = env->NewStringUTF("UTF-8");
        jclass cls = env->FindClass("java/lang/String");
        jmethodID ctor = env->GetMethodID(cls, "<init>", "([BLjava/lang/String;)V");
        jstring object = (jstring) env->NewObject(cls, ctor, array, strEncode);
        return object;
    }
    
    0 讨论(0)
  • 2020-12-02 15:45

    I also struggled with the same problem from the last day. Finally figured out a solution after a day .. I hope this reply may save someone's day..

    The problem was I was calling another function within the native function, used the returned string directly and which caused crash in android older versions

    So firstly I saved the string returned from another function to a variable then used it, and the problem gone :D

    The below example may clear your concept

    //older code with error
    //here key_ is the string from java code
    
    const char *key = env->GetStringUTFChars(key_, 0);
    const char *keyx = getkey(key).c_str();
    return env->NewStringUTF(keyx);
    

    And here is how I solved this error

    //newer code which is working
    //here key_ is the string from java code
    
    const char *key = env->GetStringUTFChars(key_, 0);
    string k = getkey(key);
    const char *keyx = k.c_str();
    return env->NewStringUTF(keyx);
    

    Happy coding :D

    0 讨论(0)
提交回复
热议问题