Konvertieren char* jstring in JNI, als char* übergeben wird, mit va_arg
Ist es notwendig zu konvertieren, char* jbyteArray, dann rufen Sie java String s contructor zum generieren eines jstring? Wie sonst kann es getan werden? Bitte helfen Sie.
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;
}
Erstens, ich verstehe nicht, warum, wenn
Er ist mit dem C-Stil. Es ist die "objektorientierte" C, wo Sie haben zu verwenden
Oh mein Gott. Sorry. Die Antwort mkaes korrekt ist.
1. Ja, der code wird kompiliert ohne Fehler in VisualStudio. Aus irgendeinem Grund bin ich nicht in der Lage, verwenden Sie einfach env-> in meinem Programm. Es ermöglicht die env-nur wie (*env). 2. Ich habe die Verwendung der Objekt-orientierten Stil. Aber wenn ich eine Funktion aufrufen, indem Sie env -> somefunc(params), es beschwert sich sagen: nicht genügend Argumente für Aufruf. Also wenn ich mit env -> somefunc(env, params), bekomme ich keine Fehler. Im neuen, um mittels JNI, also ich weiß nicht, warum bekomme ich diese Fehler und der Grund dahinter.
Weißt du, ob es möglich ist, zu passieren, die va_arg der SetByteArrayRegion als argument? Bin ich einen Fehler zu machen, gibt es?
env
Typ JNIEnv*
schreiben Sie (*env)->SomeFunc
? Dieser code kompilieren? Zweitens, wählen Sie eine der folgenden Varianten: Objekt-orientierte: env->SomeFunc(params)
oder C-Stil: SomeFunc(env, params)
.Er ist mit dem C-Stil. Es ist die "objektorientierte" C, wo Sie haben zu verwenden
(*env)->SomeFunc(env, xyz)
. Es ist völlig richtig: stackoverflow.com/a/936148/1350762Oh mein Gott. Sorry. Die Antwort mkaes korrekt ist.
1. Ja, der code wird kompiliert ohne Fehler in VisualStudio. Aus irgendeinem Grund bin ich nicht in der Lage, verwenden Sie einfach env-> in meinem Programm. Es ermöglicht die env-nur wie (*env). 2. Ich habe die Verwendung der Objekt-orientierten Stil. Aber wenn ich eine Funktion aufrufen, indem Sie env -> somefunc(params), es beschwert sich sagen: nicht genügend Argumente für Aufruf. Also wenn ich mit env -> somefunc(env, params), bekomme ich keine Fehler. Im neuen, um mittels JNI, also ich weiß nicht, warum bekomme ich diese Fehler und der Grund dahinter.
Weißt du, ob es möglich ist, zu passieren, die va_arg der SetByteArrayRegion als argument? Bin ich einen Fehler zu machen, gibt es?
InformationsquelleAutor user2358330 | 2013-06-05
Du musst angemeldet sein, um einen Kommentar abzugeben.
Könnte man nur überprüfen JNI-api-Dokumentation. E. g. Hier.
Finden Sie:
Also alles, was Sie haben, es zu tun so etwas wie dieses:
free(buf)
irgendwann oder mussNewStringUTF
machen die JVM dafür verantwortlich, dass der Speicher?Ja, müssen Sie freien Speicher selbst. Und je nach Kontext möglicherweise müssen Sie auch zu nennen
DeleteLocalRef()
auf Ihren string-Objekt.typo
(*env)->NewStringUTF(env, buf);
sollteenv->NewStringUTF(env, buf);
.Nein, es ist kein Tippfehler. Entweder Sie verwenden die c-syntax, wie ich Tat oder der c++ - syntax mit
env->NewStringUTF(buf)
. Es hängt davon ab, wie Sie möchten, kompilieren Sie Ihre native code.Oh mein Gott, tut mir Leid. Ist es richtig!!!!
InformationsquelleAutor mkaes
Es hängt von der Art Ihrer
char *
string.NewStringUTF
Kopien von einem 0-terminiert, modifizierte UTF-8 - - Codierung von Unicode-Zeichen.NewString
Kopien von einem gezählt, UTF-16 - Codierung von Unicode-Zeichen. Wenn Sie nicht haben, müssen Sie die Konvertierung.Viel code mit
NewStringUTF
ist geschrieben, mit der Annahme, dass die Zeichenfolge NUL-terminierte ASCII -. Wenn diese Annahme richtig ist, dann wird es funktionieren, da das modifizierte UTF-8-Kodierung und die ASCII-Codierung würde produzieren die gleiche byte-Reihenfolge. Dieser code sollte auch klar kommentiert, dokumentieren die Beschränkung auf die Daten der Zeichenfolge.Die Umwandlung Methode, die Sie als eine Anspielung auf das aufrufen der Java-Funktionen (z.B. String(byte[] bytes, Charset charset)) —ist ein guter. Eine alternative (in Windows, ich sehe, Sie sind mit Visual Studio) ist MultiByteToWideChar. Eine weitere alternative ist iconv.
Bottom line: Sie haben zu wissen, was Zeichensatz und-Kodierung deinen string verwendet und konvertieren Sie Sie dann in eine UTF-16 codierte Unicode-für den Einsatz als Java-String.
InformationsquelleAutor Tom Blodget
ist es besser zurück
byte[]
zu java eher alsjstring
durch den Unterschied zwischen UTF-string in der java-und der c-saite.es ist viel leichter zu behandeln Codierung problem in javain java:
in c++:
in java wieder:
Nein,es ist nicht. seitdem ich bin nicht vertraut mit jstring und das ist mit api verwenden, byte[] ist nur für die Bequemlichkeit
InformationsquelleAutor zyanlu