cs_lak75
Messages postés71Date d'inscriptionvendredi 20 juillet 2007StatutMembreDernière intervention 3 avril 2008
-
29 nov. 2007 à 17:04
cs_merioma -
14 avril 2008 à 12:47
Bonjour,
En Java, comment utiliser les fonctions de la librairie RAPI.dll pour les transferts entre Pc et Pocket ?
J'ai une appli java qui tourne sur pc avec un serveur jboss et je cherche à lire un fichier enregistré sur pda.
J'ai réussi à l'attacher, mais pas capable d'exécuter ses fonctions.
Quand je référencie la fonction CeRapiInit() par exemple:
public static native long CeRapiInit();
J'ai le message :
Error [action] Servlet.service() for servlet action threw exception
Java.lang.unsatisfieldLinkError: CeRapiInit.
cs_lak75
Messages postés71Date d'inscriptionvendredi 20 juillet 2007StatutMembreDernière intervention 3 avril 2008 3 déc. 2007 à 09:31
Salut,
merci pour les reponses,
ce que je ne comprend pas c'est que j'ai bien la dll avec les methodes
que j'ai besoin. je charge cette dll dans le programme java et je
defini des metodes natives pour les utiliser. mais ça ne marche pas.
pour quoi je suis obligé de programmer un autre programme en c pour
faire l'intermediare alors que la dll est bien ecrite en c?
et si jamais je suis obligé d'ecrire ce programme en c, est ce que
vous avez un exemple simple pour comprendre? car je ne sais pas quoi
ecrire dans le fichier et dans quel repertoire il faut le mettre?
merci pour votre aide.
Twinuts
Messages postés5375Date d'inscriptiondimanche 4 mai 2003StatutModérateurDernière intervention14 juin 2023111 3 déc. 2007 à 11:22
Salut,
java reste un langage haut niveau donc, si tu veux linker une lib dynamique avec lui, il te faut impérativement la wrapper avec une couche JNI, afin que la jvm puisse retrouver ses petits...
cs_lak75
Messages postés71Date d'inscriptionvendredi 20 juillet 2007StatutMembreDernière intervention 3 avril 2008 3 déc. 2007 à 13:56
salut,
les exemples que j'ai trouvés montrent comment on ecri un programme
en c et comment on l'utilise en java. mais moi j'ai une librairie, je
connais le nom de quelques methodes que je compte utilisé....
est ce que tu as compri mon pb?
merci
oui,
j'ai très bien compris.... et visiblement tu ne cernes pas
vraiment le but de JNI...
Pour
faire simple :
Imagine
que tu as une dll écrite en C/C++ et que tu veuilles
l'utiliser dans ton application java (ce qui est ton cas). Cette DLL
te permet d'afficher un message sur la console (le cas simple d'un
printf), pour l'utiliser tu devras wrapper les fonctions avec JNI,
exemple :
dans
la dll tu as la méthode ' void print(char *str); ' qui n'est pas
utilisable tel quelle dans ton application java. Maintenant il te
faut écrire le wrapper, donc commence par la partie java
(exemple avec une classe Print.java):
public
class Print {
static
{
//
demande à la jvm de charger ta librairie,
//
ici tu ne mets que le nom court de la lib (sans l'extension).
System.loadLibrary("Print");
}
//
ici tu précises à la JVM que le comportement de la
méthode sera fait nativement (en C ou C++)
public
native void print(String str);
}
voici
maintenant la classe java pour le test (je parlerai après de
la partie C/C++)
public
class Test {
public
static void main(String ...argv) {
Print
p = new Print();
p.print("Hello
de java\n");
}
}
Pour
exécuter l'application dans un premier temps le mieux est de
mettre l'option '-Djava.library.path= chemin' à la ligne de
lancement sinon, si tu ne veux pas te prendre la tête sous
windoz tu rajoutes la lib dans le système32.
Bref
avant de mettre en place le code C/C++, il te faut demander à
la jvm de te générer un fichier header(.h) associé
à ta classe Print.java, pour ce faire utilise la commande :
javah
-jni -verbose Print
Note
: ici Print n'est autre que le fichier Print.class (pas le .java)
Passons
au code C/C++, ici on fait appel à la fonction printf du C
(vois ça comme la fonction de ta DLL). Tu fais un projet DLL
avec ton IDE (en gros l'utilisation simple de JNI se base sur des DLL
représentant ton wrapper entre le monde java et le monde
C/C++), tu le link avec les fichiers include de la jvm(voir la doc de
ton IDE pour ajouter des includes dans le path) <jdk_version>/include
et <jdk_version>/include/tonOs, enfin tu ajoutes le fichier
Print.h à ton projet :
ton
fichier Print.h devrait ressembler à ça :
/*
DO NOT EDIT THIS FILE - it is machine generated */
#include
<jni.h>
/*
Header for class Print */
#ifndef
_Included_Print
#define
_Included_Print
/*
* Def du comportement de
la méthode java
* Class: Print
* Method: print
* Signature:
(Ljava/lang/String;)V
*/
JNIEXPORT
void JNICALL Java_Print_print (JNIEnv *env, jobject jprint, jstring
jstr) {
//variables
pour la copie de la chaine java vers C/C++
const
char *utf_string;
jboolean
isCopy;//pour tester si la copie est bonne ou non
//copie
de la chaine java
utf_string
= (*env)->GetStringUTFChars(env, jstr, &isCopy);
//affichage
de la chaine passée depuis java
printf("%s",
utf_string);
//si
la copie c'est bien passée alors on libère les
ressources
if(isCopy
JNI_TRUE)
(*env)->ReleaseStringUTFChars(env,
jstr, utf_string);
}
ATTENTION: JNIEnv ne s'utilise pas de la même façon en C et en C++,
exemple :
en
C tu fais :
(*env)->GetStringUTFChars(env,
jstr, &isCopy);
or
en C++ tu fais :
env->GetStringUTFChars(jstr,
&isCopy);
Maintenant
si tu veux des exemples plus complets, regarde dans les sources que
j'ai déposé sur ce site (il y en à 3 je crois
qui utilises du JNI à différents niveaux)
------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."
cs_lak75
Messages postés71Date d'inscriptionvendredi 20 juillet 2007StatutMembreDernière intervention 3 avril 2008 3 déc. 2007 à 18:07
Salut
Je te remercie pour l'intérêt que tu porte à mon problème.
J'ai crée une classe Test.java .Pour générer le fichier header(.h) associé a cette classe, il m?affiche cette erreur :
Error ? Illegal package name : « E:\.......\.....\TEST»
Est ce que tu as une idée ?
Merci
pour l'exemple je n'ai
pas créé de package donc essai de faire de même,
je préfère que tu maîtrises la partie sans
package, soit le cas nominal, ensuite nous verrons comment
complexifier le tout...
sinon juste pour répondre à
la question je l'ai fait dans le même dir que le rep qui
contient le fichier .class...
admettons la classe Test.class se
trouvant dans le package org.cs.test alors (si tu utilises la notion
de 'source folder' alors physiquement la classe se trouve dans le rep
'/src/org/cs/test/'
en te déplacant dans le rep
'/src/' la ligne javah donnerai :
javah -jni -verbose org.cs.test.Test
(non testé mais normalement
c'est ça... sinon remplace les '.' par des '/')
si tu as eclipse et que tu connais les
fichiers ant voici une target qui représente l'exemple (ici la
classe se trouve dans un rep bin (généralement je place
mes .java dans le rep src et les .class dans le rep bin) :
cs_lak75
Messages postés71Date d'inscriptionvendredi 20 juillet 2007StatutMembreDernière intervention 3 avril 2008 4 déc. 2007 à 09:31
Salut,
excuse moi, Si j'ai bien compri il faut ceer un projet C avec mon ide
eclipse ? et aprés il faut complier ce programme que ça soi en c ou
c++ ?
merci
bah vi, le seul moyen que
tu as de lier ta dll et ton programme java est de passer par JNI soit
par du code C/C++... pour ce qui est de l'IDE pour faire du C/C++ je
te conseil plus d'utiliser MS Visual Express, perso je suis pas sous
windoz donc utiliser eclipse et le plugin CDT pour faire du C/C++
c'est limite intuitif mais je sais par expérience que c'est la
mort de faire du C/C++ avec eclipse sous windoz
------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."
cs_lak75
Messages postés71Date d'inscriptionvendredi 20 juillet 2007StatutMembreDernière intervention 3 avril 2008 4 déc. 2007 à 10:12
Merci pour ta réponse,
Tu sais j'ai programmé une application en java sur un pda qui
enregistre des données dans un fichier (toujours sur le pda). J'ai une
autre application java (client léger) qui tourne sur pc et qui cherche
à récupérer les données enregistrées dans le fichier du pda.
le pda et le pc sont reliés par un câble usb, j'utilise activeSync
pour la synchronisation entre les deux.
je n'ai pas trouvé un moyen pour récupérer ce fichier, je pense que
le seul moyen est la librairie RAPI.dll qui est utilisée par activeSync.
Voilà mon pb.....
cs_lak75
Messages postés71Date d'inscriptionvendredi 20 juillet 2007StatutMembreDernière intervention 3 avril 2008 4 déc. 2007 à 10:58
Les fichier .class se trouvent dans /dev/build../../../../../ et les .java dans /dev/src/??./
Je me suis déplacer dans le répertoire là où il y a les .class et j'ai exécuté la commande "javah ?jni ?verbose Test" il m?affiche cette erreur :
bad class file : .\Test.class
javadoc : error ?fatal error
[search path for source file :[.]]
search path for classe file : [c:\java\jdk1.5.0\jre\lib\rt.jar
c:\java\jdk1??..]
.............
[loading .\Test.class]
2 errors
cs_lak75
Messages postés71Date d'inscriptionvendredi 20 juillet 2007StatutMembreDernière intervention 3 avril 2008 4 déc. 2007 à 11:54
Salut j'ai réussi en fin a lancer la commande javah et de generer
le fichier Test.h (je te remercie pour ton aide)
il me reste a ecrire le fichier en c, Actuellement je travaille sur
idea Intelligie.
est ce que il y a un moyen pour ecrire le code en c avec cet ide?
une autre question comment faire le lien entre les deux projets (java
et c)?
merci
Twinuts
Messages postés5375Date d'inscriptiondimanche 4 mai 2003StatutModérateurDernière intervention14 juin 2023111 4 déc. 2007 à 11:58
Salut,
pour 'idea Intelligie' je ne sais pas.
pour ce qui est du lien entre le projet c et java regarde l'exemple que je t'ai donné... et inspire toi également d'une de mes sources sur jni...
------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."
cs_lak75
Messages postés71Date d'inscriptionvendredi 20 juillet 2007StatutMembreDernière intervention 3 avril 2008 4 déc. 2007 à 14:03
J'ai une autre question,
Dans rapi.dll j'ai les méthodes CeRapiInit() et CeCopyFile() qui
m?intéressent. Dans mon programme c, est ce qu'il faut définir que
l'entête des deux méthodes?
Merci