[JNI]Conversion de chemin java->C++
Bonjour,
Je dois interfacer une dll avec mon appli Java, et je rencontre quelques soucis avec les chemins de fichiers contenant des accents.
Au départ, j'utilisais :
Code:
1 2
|
env->GetStringUTFChars(path,0); |
où env correspond à un JNIEnv* et path est une jstring.
Malheureusement les accents ne passe pas en UTF-8 (par exemple "é" devient 'A-tilde'+'sigle copyright' : code ASCII : #195 et #169)
J'ai trouvé ceci dans une doc sur JNI, mais ça ne fonctionne pas vraiment tel quel et je n'arrive pas à l'adapter :
Citation:
8.2.2 Translating jstrings to Native Strings
Use the String.getBytes method to convert a jstring to the appropriate native
encoding. The following utility function translates a jstring to a locale-specific
native C string:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| char *JNU_GetStringNativeChars(JNIEnv *env, jstring jstr)
{
jbyteArray bytes = 0;
jthrowable exc;
char *result = 0;
if ((*env)->EnsureLocalCapacity(env, 2) < 0) {
return 0; /* out of memory error */
}
bytes = (*env)->CallObjectMethod(env, jstr, MID_String_getBytes);
exc = (*env)->ExceptionOccurred(env);
if (!exc) {
jint len = (*env)->GetArrayLength(env, bytes);
result = (char *)malloc(len + 1);
if (result == 0) {
JNU_ThrowByName(env, "java/lang/OutOfMemoryError", 0);
(*env)->DeleteLocalRef(env, bytes);
return 0;
}
(*env)->GetByteArrayRegion(env, bytes, 0, len,
(jbyte *)result);
result[len] = 0; /* NULL-terminate */
} else {
(*env)->DeleteLocalRef(env, exc);
}
(*env)->DeleteLocalRef(env, bytes);
return result;
} |
Quelqu'un aurait-il déjà rencontré ce genre de problème?
Sinon, si vous voyez comment adapter le code, je suis preneur aussi...
Pour l'instant, j'ai fait ça :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
char* JNU_GetStringNativeChars(JNIEnv* env, jstring jstr) {
jbyteArray bytes = 0;
//MODIF : test avec ExceptionCheck au lieu de ExceptionOccured (pas reconnu) => plus besoin de exc
// jthrowable exc;
char* result = 0;
if (env->EnsureLocalCapacity(2) < 0) {
return 0; // out of memory error
}
//MODIF : redéfinition de MID_String_getBytes qui n'est pas connu apparemment
jclass cls = env->GetObjectClass(jstr);
// jmethodID mid = (*env)->GetMethodID(env, cls, "toString", "()Ljava/lang/String;");
jmethodID MID_String_getBytes = env->GetMethodID(cls, "getBytes", "(Ljava/lang/String;)[B");
//MODIF : casté pour que ça marche...
// bytes = env->CallObjectMethod(jstr, MID_String_getBytes);
bytes = (jbyteArray) env->CallObjectMethod(jstr, MID_String_getBytes);
byte bytesC[] = env->GetByteArrayElements(bytes,0);
// printf("%d\n", bytes->)
//MODIF : test avec ExceptionCheck au lieu de ExceptionOccured. (pas reconnu)..
// exc = env->ExceptionOccured();
jboolean exc = env->ExceptionCheck();
if (!exc) {
printf("pas d'exception\n");
jint len = env->GetArrayLength(bytes);
result = (char*)malloc(len+1);
if (result == 0) {
JNU_ThrowByName(env, "java/lang/OutOfMemoryError", 0);
env->DeleteLocalRef(bytes);
return 0;
}
env->GetByteArrayRegion(bytes, 0, len, (jbyte*)result);
result[len] = 0; // NULL-terminate
}
else {
//MODIF : test avec ExceptionCheck au lieu de ExceptionOccured (pas reconnu) => plus besoin de exc
printf("Exception occured...\n");
// env->DeleteLocalRef(exc);
}
env->DeleteLocalRef(bytes);
return result;
} |