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 :
où env correspond à un JNIEnv* et path est une jstring.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 env->GetStringUTFChars(path,0);
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 :
Quelqu'un aurait-il déjà rencontré ce genre de problème?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 : Sélectionner tout - Visualiser dans une fenêtre à part
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; }
Sinon, si vous voyez comment adapter le code, je suis preneur aussi...
Pour l'instant, j'ai fait ça :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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; }
Partager