当使用va_arg传递char*时,在JNI中将char*转换为jstring
Convert char* to jstring in JNI, when char* is passed using va_arg
是否有必要将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 < size; i++) {
jclass clazz;
jmethodID id;
jobject obj;
jobject encoding;
switch (sig[i]) {
case 'i': {
clazz = (*env)->FindClass(env, "java/lang/Integer");
id = (*env)->GetMethodID(env, clazz, "<init>", "(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, "<init>", "(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, "<init>", "([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 *
字符串的性质。NewStringUTF
从以0结尾的修改过的UTF-8编码的Unicode字符复制。NewString
从计数,UTF-16编码的Unicode字符复制。如果两者都没有,就必须执行转换。
许多使用NewStringUTF
的代码都假定字符串是以空结束的ASCII。如果这个假设是正确的,那么它将工作,因为修改后的UTF-8编码和ASCII编码将产生相同的字节序列。这样的代码应该有明确的注释,以记录对字符串数据的限制。
您提到的转换方法—调用Java函数(例如String(byte[] bytes, Charset Charset))—是一个很好的方法。另一种选择(在Windows中,我看到你正在使用Visual Studio)是MultiByteToWideChar。另一个选项是iconv.
底线:您必须知道字符集和编码您的字符串使用,然后将其转换为UTF-16编码的Unicode作为Java字符串使用。
由于java和c字符串中的UTF字符串之间的差异,最好返回byte[]
而不是jstring
。在java中处理编码问题要容易得多
byte[] otherString = nativeMethod("javastring".getBytes("UTF-8"))
在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 ;
Java中的:
new String(otherString);
相关文章:
- 为char数组调整zlib-zpipe
- 使用strcpy将char数组的元素复制到另一个数组
- 为什么 Serial.println(<char[]>);返回随机字符?
- 如何通过 JNI 将 java CharSequence 转换为 c++ char*
- 在 JNI 中使用错误的代码将 jbytearray 转换为 char*
- 如何使用JNI返回C char 2D数组
- 如何将 ArrayList<byte[]> 转换为 JNI 的 vector<char[]>?
- 适当的JNI转换将数组项目从jobjectarray到分开const char
- 使用 char[] 参数通过 JNI 调用方法
- Unicode const char* to JString using JNI and C++
- JNI调用将jstring转换为char*
- jni String to *char and java.lang.UnsatisfiedLinkError:
- 从 JNI 到 Java 的 char 向量
- Java - JNI - 将UCS-2字符转换为jchar(即Java的char)
- 当使用va_arg传递char*时,在JNI中将char*转换为jstring
- JNI:来自unsigned char*的位图始终为null
- Android将char数组发送到JNI c++
- 如何使用jni在c++中将数据从javaInputStream移动到char*
- 如何在JNI中将char*转换为jcharArray
- Java JNI UnsatisfiedLinkError C char pointer to pointer