Charger une dll en java

cs_lak75 Messages postés 71 Date d'inscription vendredi 20 juillet 2007 Statut Membre Derniè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.

Est-ce que quelqu'un à une idée ?
Merci

75 réponses

Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
29 nov. 2007 à 19:46
Salut,

il te faut écrire un wrapper JNI

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
0
cs_lak75 Messages postés 71 Date d'inscription vendredi 20 juillet 2007 Statut Membre Dernière intervention 3 avril 2008
30 nov. 2007 à 09:23
C'est-à-dire ? Je n'ai pas très bien compris ?
Merci
0
Utilisateur anonyme
30 nov. 2007 à 22:06
System.load("c:/ton_chemin/ta_lib.dll");





0
Utilisateur anonyme
1 déc. 2007 à 00:11
essaie loadLibrary sinon

0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
1 déc. 2007 à 11:01
Salut,

cela ne suffit pas....regarde ICI tu comprendra peut-être ce qu'est le JNI et pourquoi tu dois l'utiliser pour faire ce que tu veux...

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
0
cs_lak75 Messages postés 71 Date d'inscription vendredi 20 juillet 2007 Statut Membre Derniè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.
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
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...

regarde sur le lien ci-dessous pour une explication :
http://en.wikipedia.org/wiki/Java_Native_Interface

et sur celui-ci pour le tutos :
http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jni.html

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
0
cs_lak75 Messages postés 71 Date d'inscription vendredi 20 juillet 2007 Statut Membre Derniè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
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
3 déc. 2007 à 15:12
<meta http-equiv= "CONTENT-TYPE" content="text/html; charset=utf-8" />
<title>
</title>
<meta name="GENERATOR" content="OpenOffice.org 2.3 (Linux)" />
<style type="text/css">
<!--
@page { size: 21cm 29.7cm; margin: 2cm }
P { margin-bottom: 0.21cm }
-->
</style>


Salut,

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








    #ifdef
__cplusplus








        extern
"C" {








    #endif








    /*
    * Class: Print
    * Method: print
    * Signature:
(Ljava/lang/String;)V
    */








    JNIEXPORT
void JNICALL Java_Print_print (JNIEnv *, jobject,
jstring);








    #ifdef
__cplusplus
        }
    #endif
#endif












maintenant
tu codes le fichier Print.c (pourquoi pas) en lui indiquant le dll
main (c'est la faute à windoz si il faut même un 'main'
dans une DLL)







Note:
ici je ne vais pas brider l'exemple à windoz donc tu peux
faire abstraction aux '#ifdef' et '#endif'.







#include
<stdio.h>
#include
"Print.h"








//
notre dll main
#ifdef
WIN32
    #include
<windows.h>








    bool
WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID
lpvReserved){
        return
TRUE;
    }
#endif























/*
* 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 ..."

OoWORAoO
0
cs_lak75 Messages postés 71 Date d'inscription vendredi 20 juillet 2007 Statut Membre Derniè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
0
cs_lak75 Messages postés 71 Date d'inscription vendredi 20 juillet 2007 Statut Membre Dernière intervention 3 avril 2008
3 déc. 2007 à 18:11
voilà le message d'erreur affiché :
javadoc : Error ? Illegal package name : « E:\.......\.....\TEST»
0
cs_lak75 Messages postés 71 Date d'inscription vendredi 20 juillet 2007 Statut Membre Dernière intervention 3 avril 2008
3 déc. 2007 à 18:24
il faut lancer la commande : javah -jni -verbose dans quel repertoire ?

je l'ai lancer dans le repertoire là ou il y a mon fichier .class
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
3 déc. 2007 à 20:10
<meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8" />
<title>
</title>
<meta name="GENERATOR" content="OpenOffice.org 2.3 (Unix)" />
<style type="text/css">
<!--
@page { size: 21cm 29.7cm; margin: 2cm }
P { margin-bottom: 0.21cm }
-->
</style>
Salut,

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) :


<target name="unNom">


<javah classpath="./bin"
verbose="yes" force="yes"
destdir="<chemin_du_projet_c_c++>/src/<destination>/">


<class name="org.cs.test.Test"/>


</javah>


</target>







------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
0
cs_lak75 Messages postés 71 Date d'inscription vendredi 20 juillet 2007 Statut Membre Derniè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
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
4 déc. 2007 à 09:37
<meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8" />
<title>
</title>
<meta name="GENERATOR" content="OpenOffice.org 2.3 (Linux)" />
<style type="text/css">
<!--
@page { size: 21cm 29.7cm; margin: 2cm }
P { margin-bottom: 0.21cm }
-->
</style>
Salut,

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 ..."

OoWORAoO
0
cs_lak75 Messages postés 71 Date d'inscription vendredi 20 juillet 2007 Statut Membre Derniè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.....
0
cs_lak75 Messages postés 71 Date d'inscription vendredi 20 juillet 2007 Statut Membre Derniè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

est ce que tu as une idée sur ces erreurs?
merci
0
cs_lak75 Messages postés 71 Date d'inscription vendredi 20 juillet 2007 Statut Membre Derniè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
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
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 ..."

OoWORAoO
0
cs_lak75 Messages postés 71 Date d'inscription vendredi 20 juillet 2007 Statut Membre Derniè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
0
Rejoignez-nous