Bonjour à tous,

dans le cadre d'un projet je souhaite utiliser une API fournie en Java sous la forme d'un Jar depuis une appli en C++. J'ai donc utilisé JNI. Dans un premier temps ça marchait bien car j'avais créé une interface static en java mais l'API étant un produit appelé à évoluer il faudrait pouvoir éviter d'utiliser l'interface et donc faire les appels directs aux classes via JNI et là je coince.

Tout d'abord, j'ai une confusion étrange dans mon code entre classe et instance. En principe l'appel àa la méthode Call<type>Method se fait sur l'instance et pourtant dans mon cas, cet appel plante et je dois faire l'appel en lui passant la classe, ce qui me semble aller à l'encontre du principe du Call<type>Method.

Enfin mes autres appels à Call<type>Method plantent avec acharnement, alors si quelqu'un pouvait éclairer ma lanterne.

Pour info je suis avec Visual C++ 2005 et une JRE 1.5.0.18 et JNI 1.4

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
cls = (*env).FindClass("chemin/vers/la/classe"); // recuperation de la classe
 
	// gestion des exceptions remontees depuis la JVM si necessaire
	if ((*env).ExceptionCheck()) {
		(*env).ExceptionDescribe();
         cout << "Une erreur est survenue!\n";
    }
	// gestion en cas d'erreur cote C++
	if (cls == 0){
		fprintf(stderr, "Unable to load class file\n Error is :%ld\n ", cls);
        exit(1);
	}
	midInit = (*env).GetMethodID(cls, "<init>", "()V"); 
	// gestion des exceptions remontees depuis la JVM si necessaire
	if ((*env).ExceptionCheck()) {
		(*env).ExceptionDescribe();
         cout << "Une erreur est survenue!\n";
    }
	// gestion en cas d'erreur cote C++
	if (midInit == 0){
		fprintf(stderr, "Unable to find method\n Error is :%ld\n ", midInit);
		exit(1);
	}
 
	jobject objetJava = (*env).CallObjectMethod(cls, midInit);
 
    midMethode1 = (*env).GetMethodID(cls, "methode1", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V"); //recuparation de l'identifiant de la methode gra^ce au nom et a sa signature
	// gestion des exceptions remontees depuis la JVM si necessaire
	if ((*env).ExceptionCheck()) {
		(*env).ExceptionDescribe();
         cout << "Une erreur est survenue!\n";
    }
	// gestion en cas d'erreur cote C++
	if (midMethode1 == 0){
		fprintf(stderr, "Unable to find method\n Error is :%ld\n ", midMethode1);
		exit(1);
	}
 
	char sRemise[] = "";
	char sComplement[] = "";
	char sNumero[] = "";
	char sVoie[] = "PAG";
	char sService[] = "";
	char sCodePostal[] = "44000";
	char sLocalite[] = "NANTES";
 
	// alimentation du tableau avec transformation des donnees char de C++ en String Java
	jstring jsL1  = (*env).NewStringUTF("");
	jstring jsL2  = (*env).NewStringUTF(sRemise);
	jstring jsL3  = (*env).NewStringUTF(sComplement);
	jstring jsL41 = (*env).NewStringUTF(sNumero);
	jstring jsL42 = (*env).NewStringUTF(sVoie);
	jstring jsL5  = (*env).NewStringUTF(sService);
	jstring jsL61 = (*env).NewStringUTF(sCodePostal);
	jstring jsL62 = (*env).NewStringUTF(sLocalite);
	jint jiNorme = 38;
 
	// invcation de la methode grace a son identifiant et recuperation de la valeur retournee dans une jstring
	(*env).CallVoidMethod(objetJava, midMethode1, jsL1,jsL2,jsL3,jsL41,jsL42,jsL5,jsL61,jsL62,jiNorme);
	// gestion des exceptions remontees depuis la JVM si necessaire
	if ((*env).ExceptionCheck()) {
		(*env).ExceptionDescribe();
         cout << "Une erreur est survenue!\n";
    }
	cout << "Methode1 fait" << endl;
	midControle = (*env).GetMethodID(cls, "controle", "()V"); 
	// gestion des exceptions remontees depuis la JVM si necessaire
	if ((*env).ExceptionCheck()) {
		(*env).ExceptionDescribe();
         cout << "Une erreur est survenue!\n";
    }
	// gestion en cas d'erreur cote C++
	if (midControle == 0){
		fprintf(stderr, "Unable to find method\n Error is :%ld\n ", midControle);
		exit(1);
	}
 
	(*env).CallVoidMethod(objetJava, midControle);
	if ((*env).ExceptionCheck()) {
		(*env).ExceptionDescribe();
         cout << "Une erreur est survenue!\n";
    }
Dans ce code si au moment de l'invocation de la méthode Methode1, je remplace objetJava par cls, je n'ai pas le plantage.

Je n'ai malheureusement pas de log, le crash coté C++ est brutal;