Convert char* to jstring in JNI, when char* is passed using va_arg

后端 未结 3 494
不思量自难忘°
不思量自难忘° 2020-12-06 17:23

Is it necessary to convert char* to jbyteArray, then call java String\'s contructor to generate a jstring? How else can it be done? Please help.

static in         


        
相关标签:
3条回答
  • 2020-12-06 17:36

    It depends on the nature of your char * string. NewStringUTF copies from a 0-terminated, modified UTF-8 encoding of Unicode characters. NewString copies from a counted, UTF-16 encoding of Unicode characters. If you don't have either of those, you have to perform a conversion.

    A lot of code using NewStringUTF is written with the assumption that the string is NUL-terminated ASCII. If that assumption is correct then it will work because the modified UTF-8 encoding and the ASCII encoding would produce the same byte sequence. Such code should be clearly commented to document the restriction on the string data.

    The conversion method you allude to—calling Java functions (e.g. String(byte[] bytes, Charset charset)) —is a good one. One alternative (in Windows, I see you are using Visual Studio) is MultiByteToWideChar. Another alternative is iconv.

    Bottom line: You have to know what character set and encoding your string uses and then convert it to a UTF-16 encoded Unicode for use as a Java String.

    0 讨论(0)
  • 2020-12-06 17:47

    it is better to return byte[] to java rather than jstring due to the difference between UTF string in java and c string.it's much easier to deal encoding problem in java

    in java:

    byte[] otherString = nativeMethod("javastring".getBytes("UTF-8"))
    

    in c++:

    jbyte* javaStringByte = env->GetByteArrayElements(javaStringByteArray, NULL);
    jsize javaStringlen = env->GetArrayLength(javaStringByteArray);
    std::vector<char> vjavaString;
    vjavaString.assign(javaStringByte , javaStringByte + tokenlen);
    std::string cString(vjavaString.begin(), vjavaString.end());
    //
    // do your stuff ..
    //
    jsize otherLen = otherCString.size();
    jbyteArray otherJavaString = env->NewByteArray(otherLen);
    env->SetByteArrayRegion(otherJavaString , 0, otherLen , (jbyte*) &otherJavaString [0]);
    
    env->ReleaseByteArrayElements(javaStringByteArray, javaStringByte , JNI_ABORT);
    return otherJavaString ;
    

    in java again:

    new String(otherString);
    
    0 讨论(0)
  • 2020-12-06 17:56

    You could just check JNI api documentation. E.g. Here.
    You will find:

    jstring NewStringUTF(JNIEnv *env, const char *bytes);
    

    So all you have to do it something like this:

    char *buf = (char*)malloc(10);
    strcpy(buf, "123456789"); // with the null terminator the string adds up to 10 bytes
    jstring jstrBuf = (*env)->NewStringUTF(env, buf);
    
    0 讨论(0)
提交回复
热议问题