bonjour je fais appel à vous car j'ai un problème. je suis actuellement sur un projet avec comme langage de programmation Java.
Mon projet consiste à faire fonctionner une carte velleman k8055 en java sauf que le hic, c'est que la carte est dans un autre langage le C++.
Après plusieurs recherches je suis parvenu à trouver une solution pour utiliser la carte en java, c'est le JNI (Java Native Interface), je ne suis pas un expert donc j'ai beaucoup de mal à comprendre.
voilà mon problème, j'ai codé en premier une classe pour appeler la carte k8055 en java : JavaK8055Call.java
- Je la compile : javac JavaK8055Call.java
- Un fichier JavaK8055Call.class se crée
- ensuite je crée un fichier natif depuis le programme java en C++: javah JavaK8055Call
Le code natif JavaK8055Call.h est crée
- ensuite je crée un programme depuis le .h natif: JavaK8055Call.cpp
- Je compile le JavaK8055Call.cpp et aussi le k8055.cpp de la classe de base en mettant je crois le lien où est stocké le jni.h que je dois utiliser. Ça ressemble à cela : g++ -c -fPIC -I"/usr/lib/jvm/java-7-openjdk-amd64/include/" -I"/usr/lib/jvm/java-7-openjdk-amd64/include/linux" -o test1.o k8055.cpp
g++ -c -fPIC -I"/usr/lib/jvm/java-7-openjdk-amd64/include/" -I"/usr/lib/jvm/java-7-openjdk-amd64/include/linux" -o test.o JavaK8055Call.cpp
- Ensuite je crée une librairie partagée: g++ -shared -fPIC -o libJavaK8055Call.so test1.o
et pour finir j’exécute le programme en java : java -Djava.library.path=. JavaK8055Call
Voilà l'erreur que je reçois après l'exécution:
root@debian:/home/user/TestJ# java -Djava.library.path=. JavaK8055Call
Exception in thread "main" java.lang.UnsatisfiedLinkError: JavaK8055Call.OpenDevice()V
at JavaK8055Call.OpenDevice(Native Method)
at JavaK8055Call.main(JavaK8055Call.java:44)
JavaK8055Call.java
JavaK8055Call.h
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 class JavaK8055Call { static { System.loadLibrary("JavaK8055Call"); } public native void OpenDevice(); public native int CloseDevice(); public native long ReadAnalogChannel(long Channel); public native int ReadAllAnalog(LongWrapper Data1, LongWrapper Data2); public native int OutputAnalogChannel(long Channel, long Data); public native int OutputAllAnalog(long Data1, long Data2); public native int ClearAnalogChannel(long Channel); public native int ClearAllAnalog(); public native int SetAnalogChannel(long Channel); public native int SetAllAnalog(); public native int WriteAllDigital(long Data); public native int ClearDigitalChannel(long Channel); public native int ClearAllDigital(); public native int SetDigitalChannel(long Channel); public native int SetAllDigital(); public native int ReadDigitalChannel(long Channel); public native long ReadAllDigital(); public native long ReadCounter(long CounterNr); public native int ResetCounter(long CounterNr); public native int SetCounterDebounceTime(long CounterNr, long DebounceTime); public static void main(String[] args) { /*JavaK8055Call k8055 = new JavaK8055Call(); System.out.println("0"); k8055.OpenDevice(); System.out.println("1"); k8055.CloseDevice(); System.out.println("2"); */ new JavaK8055Call().OpenDevice(); } }
JavaK8055Call.cpp
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174 /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class JavaK8055Call */ #ifndef _Included_JavaK8055Call #define _Included_JavaK8055Call #ifdef __cplusplus extern "C" { #endif /* * Class: JavaK8055Call * Method: OpenDevice * Signature: ()V */ JNIEXPORT void JNICALL Java_JavaK8055Call_OpenDevice (JNIEnv *, jobject); /* * Class: JavaK8055Call * Method: CloseDevice * Signature: ()I */ JNIEXPORT jint JNICALL Java_JavaK8055Call_CloseDevice (JNIEnv *, jobject); /* * Class: JavaK8055Call * Method: ReadAnalogChannel * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_JavaK8055Call_ReadAnalogChannel (JNIEnv *, jobject, jlong); /* * Class: JavaK8055Call * Method: ReadAllAnalog * Signature: (LLongWrapper;LLongWrapper;)I */ JNIEXPORT jint JNICALL Java_JavaK8055Call_ReadAllAnalog (JNIEnv *, jobject, jobject, jobject); /* * Class: JavaK8055Call * Method: OutputAnalogChannel * Signature: (JJ)I */ JNIEXPORT jint JNICALL Java_JavaK8055Call_OutputAnalogChannel (JNIEnv *, jobject, jlong, jlong); /* * Class: JavaK8055Call * Method: OutputAllAnalog * Signature: (JJ)I */ JNIEXPORT jint JNICALL Java_JavaK8055Call_OutputAllAnalog (JNIEnv *, jobject, jlong, jlong); /* * Class: JavaK8055Call * Method: ClearAnalogChannel * Signature: (J)I */ JNIEXPORT jint JNICALL Java_JavaK8055Call_ClearAnalogChannel (JNIEnv *, jobject, jlong); /* * Class: JavaK8055Call * Method: ClearAllAnalog * Signature: ()I */ JNIEXPORT jint JNICALL Java_JavaK8055Call_ClearAllAnalog (JNIEnv *, jobject); /* * Class: JavaK8055Call * Method: SetAnalogChannel * Signature: (J)I */ JNIEXPORT jint JNICALL Java_JavaK8055Call_SetAnalogChannel (JNIEnv *, jobject, jlong); /* * Class: JavaK8055Call * Method: SetAllAnalog * Signature: ()I */ JNIEXPORT jint JNICALL Java_JavaK8055Call_SetAllAnalog (JNIEnv *, jobject); /* * Class: JavaK8055Call * Method: WriteAllDigital * Signature: (J)I */ JNIEXPORT jint JNICALL Java_JavaK8055Call_WriteAllDigital (JNIEnv *, jobject, jlong); /* * Class: JavaK8055Call * Method: ClearDigitalChannel * Signature: (J)I */ JNIEXPORT jint JNICALL Java_JavaK8055Call_ClearDigitalChannel (JNIEnv *, jobject, jlong); /* * Class: JavaK8055Call * Method: ClearAllDigital * Signature: ()I */ JNIEXPORT jint JNICALL Java_JavaK8055Call_ClearAllDigital (JNIEnv *, jobject); /* * Class: JavaK8055Call * Method: SetDigitalChannel * Signature: (J)I */ JNIEXPORT jint JNICALL Java_JavaK8055Call_SetDigitalChannel (JNIEnv *, jobject, jlong); /* * Class: JavaK8055Call * Method: SetAllDigital * Signature: ()I */ JNIEXPORT jint JNICALL Java_JavaK8055Call_SetAllDigital (JNIEnv *, jobject); /* * Class: JavaK8055Call * Method: ReadDigitalChannel * Signature: (J)I */ JNIEXPORT jint JNICALL Java_JavaK8055Call_ReadDigitalChannel (JNIEnv *, jobject, jlong); /* * Class: JavaK8055Call * Method: ReadAllDigital * Signature: ()J */ JNIEXPORT jlong JNICALL Java_JavaK8055Call_ReadAllDigital (JNIEnv *, jobject); /* * Class: JavaK8055Call * Method: ReadCounter * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_JavaK8055Call_ReadCounter (JNIEnv *, jobject, jlong); /* * Class: JavaK8055Call * Method: ResetCounter * Signature: (J)I */ JNIEXPORT jint JNICALL Java_JavaK8055Call_ResetCounter (JNIEnv *, jobject, jlong); /* * Class: JavaK8055Call * Method: SetCounterDebounceTime * Signature: (JJ)I */ JNIEXPORT jint JNICALL Java_JavaK8055Call_SetCounterDebounceTime (JNIEnv *, jobject, jlong, jlong); #ifdef __cplusplus } #endif #endif
je tiens à dire que tous mes fichiers sont dans le même dossier.
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135 #include <jni.h> #include "JavaK8055Call.h" #include <iostream> #include <k8055.h> using namespace std; JNIEXPORT void JNICALL Java_JavaK8055Call_OpenDevice(/*JNIEnv *env, jobject obj*/) { cout<<"Ouverture du port"<<endl; //return OpenDevice(); } JNIEXPORT jint JNICALL Java_JavaK8055Call_CloseDevice(JNIEnv *env, jobject obj) { cout<<"Fermeture du port"<<endl; return CloseDevice(); } JNIEXPORT jlong JNICALL Java_JavaK8055Call_ReadAnalogChannel(JNIEnv *env, jobject obj, jlong Channel) { return ReadAnalogChannel(Channel); } JNIEXPORT jint JNICALL Java_JavaK8055Call_ReadAllAnalog(JNIEnv *env, jobject obj, jobject Data1, jobject Data2) { jclass cls = env->FindClass("LongWrapper"); /*if(cls == NULL) env->ThrowNew(exception, "Exception triggered from JNI routine : Cannot find k8055.LongWrapper"); */ jmethodID midGet = env->GetMethodID(cls, "getLong", "()J"); jmethodID midSet = env->GetMethodID(cls, "setLong", "(J)V"); /* if(midGet == NULL) env->ThrowNew(exception, "Exception triggered from JNI routine : Cannot find k8055.LongWrapper.getLong()"); if(midSet == NULL) env->ThrowNew(exception, "Exception triggered from JNI routine : Cannot find k8055.LongWrapper.setLong()"); */ jlong DataLong1 = env->CallLongMethod(Data1, midGet); jlong DataLong2 = env->CallLongMethod(Data2, midGet); int ret = ReadAllAnalog((long *)(&DataLong1), (long *)(&DataLong2)); env->CallObjectMethod(Data1, midSet, DataLong1); env->CallObjectMethod(Data2, midSet, DataLong2); return ret; } JNIEXPORT jint JNICALL Java_JavaK8055Call_OutputAnalogChannel(JNIEnv *env, jobject obj, jlong Channel, jlong Data) { return OutputAnalogChannel(Channel, Data); } JNIEXPORT jint JNICALL Java_JavaK8055Call_OutputAllAnalog(JNIEnv *env, jobject obj, jlong Data1, jlong Data2) { return OutputAllAnalog(Data1, Data2); } JNIEXPORT jint JNICALL Java_JavaK8055Call_ClearAnalogChannel(JNIEnv *env, jobject obj, jlong Channel) { return ClearAnalogChannel(Channel); } JNIEXPORT jint JNICALL Java_JavaK8055Call_ClearAllAnalog(JNIEnv *env, jobject obj) { return ClearAllAnalog(); } JNIEXPORT jint JNICALL Java_JavaK8055Call_SetAnalogChannel(JNIEnv *env, jobject obj, jlong Channel) { return SetAnalogChannel(Channel); } JNIEXPORT jint JNICALL Java_JavaK8055Call_SetAllAnalog(JNIEnv *env, jobject obj) { return SetAllAnalog(); } JNIEXPORT jint JNICALL Java_JavaK8055Call_WriteAllDigital(JNIEnv *env, jobject obj, jlong Data) { return WriteAllDigital(Data); } JNIEXPORT jint JNICALL Java_JavaK8055Call_ClearDigitalChannel(JNIEnv *env, jobject obj, jlong Channel) { return ClearDigitalChannel(Channel); } JNIEXPORT jint JNICALL Java_JavaK8055Call_ClearAllDigital(JNIEnv *env, jobject obj) { return ClearAllDigital(); } JNIEXPORT jint JNICALL Java_JavaK8055Call_SetDigitalChannel(JNIEnv *env, jobject obj, jlong Channel) { return SetDigitalChannel(Channel); } JNIEXPORT jint JNICALL Java_JavaK8055Call_SetAllDigital(JNIEnv *env, jobject obj) { return SetAllDigital(); } JNIEXPORT jint JNICALL Java_JavaK8055Call_ReadDigitalChannel(JNIEnv *env, jobject obj, jlong Channel) { return ReadDigitalChannel(Channel); } JNIEXPORT jlong JNICALL Java_JavaK8055Call_ReadAllDigital(JNIEnv *env, jobject obj) { return ReadAllDigital(); } JNIEXPORT jlong JNICALL Java_JavaK8055Call_ReadCounter(JNIEnv *env, jobject obj, jlong CounterNr) { return ReadCounter(CounterNr); } JNIEXPORT jint JNICALL Java_JavaK8055Call_ResetCounter(JNIEnv *env, jobject obj, jlong CounterNr) { return ResetCounter(CounterNr); } JNIEXPORT jint JNICALL Java_JavaK8055Call_SetCounterDebounceTime(JNIEnv *env, jobject obj, jlong CounterNr, jlong DebounceTime) { return SetCounterDebounceTime(CounterNr, DebounceTime); }
En espérant avoir une réponse positive
Cordialement
Partager