当使用va_arg传递char *时,将char *转换为JNI中的jstring

是否有必要将char *转换为jbyteArray,然后调用java String的构造函数来生成jstring? 怎么办呢? 请帮忙。

static int testhandler(void *arg, ...) { int i; struct callback *cb = (struct callback *)arg; JNIEnv *env = cb->env; char *sig = cb->signature; jint size = (jint) strlen(sig); jint size1; va_list arguments; jobjectArray return_array; jclass obj_class; jbyteArray bytes; jstring str; obj_class = (*env)->FindClass(env, "java/lang/Object"); return_array = (*env)->NewObjectArray(env, size, obj_class, NULL); va_start(arguments, arg); for (i = 0; i FindClass(env, "java/lang/Integer"); id = (*env)->GetMethodID(env, clazz, "", "(I)V"); obj = (*env)->NewObject(env, clazz, id, va_arg(arguments, uint32_t)); (*env)->SetObjectArrayElement(env, return_array, i, obj); break; } case 'l': { clazz = (*env)->FindClass(env, "java/lang/Long"); id = (*env)->GetMethodID(env, clazz, "", "(J)V"); obj = (*env)->NewObject(env, clazz, id, va_arg(arguments, uint64_t)); (*env)->SetObjectArrayElement(env, return_array, i, obj); break; } case 's': { clazz = (*env)->FindClass(env, "java/lang/String"); size1 = (jint) strlen(va_arg(arguments, char *)); id = (*env)->GetMethodID(env, clazz, "", "([BLjava/lang/String;)V"); encoding = (*env)->NewStringUTF(env, va_arg(arguments, char *)); bytes = (*env)->NewByteArray(env, size1); (*env)->SetByteArrayRegion(env, bytes, 0, size1, (jbyte *)(va_arg(arguments, char *))); str = (jstring)(*env)->NewObject(env, clazz, id , bytes); obj = (*env)->NewObject(env, clazz, id, str); (*env)->SetObjectArrayElement(env, return_array, i, obj); break; } default: { printf("unknown signature char '%c'\n", sig[i]); } } } va_end(arguments); (*env)->CallVoidMethod(env, cb->handler, cb->id, return_array); return 0; } 

您可以查看JNI api文档。 在这里 。
你会找到:

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

所以你必须这样做:

 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); 

这取决于char *字符串的性质。 NewStringUTF0端接,修改后的UTF-8 Unicode字符编码进行复制。 NewString从Unicode字符的UTF-16编码中复制。 如果您没有其中任何一个,则必须执行转换。

使用NewStringUTF大量代码是在假设字符串是NUL终止的ASCII的情况下编写的。 如果该假设是正确的,那么它将起作用,因为修改的UTF-8编码和ASCII编码将产生相同的字节序列。 应明确注释此类代码以记录对字符串数据的限制。

您提到的调用Java函数的转换方法(例如String(byte [] bytes,Charset charset) ) – 是一个很好的方法。 另一种选择(在Windows中,我看到你使用的是Visual Studio)是MultiByteToWideChar 。 另一种选择是iconv。

结论:您必须知道字符串使用的字符集和编码 ,然后将其转换为UTF-16编码的Unicode以用作Java字符串。

由于java和UT字符串中的UTF字符串之间的差异,最好将byte[]返回到java而不是jstring在java中处理编码问题要容易得多

在java中:

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

在c ++中:

 jbyte* javaStringByte = env->GetByteArrayElements(javaStringByteArray, NULL); jsize javaStringlen = env->GetArrayLength(javaStringByteArray); std::vector 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 ; 

再次在java中:

 new String(otherString);