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
は、Unicode文字の0で終了し、変更されたUTF-8エンコーディングからコピーします。 NewString
は、Unicode文字のカウントされたUTF-16エンコーディングからコピーします。これらのいずれもない場合は、変換を実行する必要があります。
NewStringUTF
を使用する多くのコードは、文字列がNULで終了するASCIIであるという前提で記述されています。その仮定が正しい場合、修正されたUTF-8エンコーディングとASCIIエンコーディングは同じバイトシーケンスを生成するため、機能します。このようなコードは、文字列データの制限を文書化するために明確にコメントする必要があります。 。
想定している変換方法-呼び出しJava関数(例String(byte [] bytes、Charset charset))—良い方法です。1つの代替手段(Windowsでは、Visual Studioを使用しているようです)は MultiByteToWideChar です。別の代替手段はiconvです。
結論:文字列が何を使用しているか文字セットとエンコーディングを把握し、UTF-16エンコードに変換する必要があります。 Java文字列として使用するUnicode。
Javaとc文字列のUTF文字列が異なるため、jstring
ではなくbyte[]
をJavaに戻す方が適切です。 。それはJavaでのエンコーディングの問題を処理する方がはるかに簡単です
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);