IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Méthode native en Java


Sujet :

Langage Java

  1. #1
    Membre confirmé
    Inscrit en
    Novembre 2007
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 106
    Par défaut Méthode native en Java
    Bonjour,

    Je cherche à utiliser une DLL dans mon application Java.

    Pour cela, j'ai utilisé une méthode native coucou() que j'ai définie dans la classe Test.java.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public class Test
    {
       static {System.loadLibrary("Projet"); }
       public native int coucou();
        public Test(){}
    }
    A partir de cette classe je génère un fichier Test.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
    #include <jni.h>
    #ifndef _Included_Test
    #define _Included_Test
    #ifdef __cplusplus
    extern "C" {
    #endif
     
    JNIEXPORT jint JNICALL Java_Test_coucou
      (JNIEnv *, jobject);
     
    #ifdef __cplusplus
    }
    #endif
    #endif
    Avec Visual C++, j'ai créé un projet que j'ai nommé "Projet"

    J'ai un programme Test.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include "Test.h"
    #include <windows.h>
    BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved){
            return TRUE;
        }
     
    JNIEXPORT jint JNICALL Java_Test_coucou (JNIEnv *env, jobject jtest) {
        // je retourne une valeur egale à 1
        return 1;
    }
    J'ai aussi défini un Test.def dans le projet C :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    EXPORTS
    Java_Test_coucou
    Pendant l'exécution j'ai toujours cette ereur dans la console du serveur JBoss :
    java.lang.UnsatisfieldLinkError : coucou at .. (Native Method)
    Quelqu'un aurait-il une idée du problème ?

    Merci d'avance pour votre aide.

  2. #2
    Rédacteur
    Avatar de CyberChouan
    Homme Profil pro
    Directeur technique
    Inscrit en
    Janvier 2007
    Messages
    2 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 752
    Par défaut
    Commence par essayer d'intégrer ta méthode native dans un programme java standalone. Quand ça fonctionnera, tu essayeras de porter ça sur un serveur d'appli. Là tu t'attaques à tous les problèmes en même temps ce qui rend plus difficile l'identification du point qui pose problème.

    PS: et pense aux balises CODE pour la lisibilité de ton post...
    Avant de poster, pensez à regarder la FAQ, les tutoriaux, la Javadoc (de la JRE que vous utilisez) et à faire une recherche
    Je ne réponds pas aux questions techniques par MP: les forums sont faits pour ça
    Mes articles et tutoriaux & Mon blog informatique

  3. #3
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    2 questions :

    - ta classe est dans un package ?
    - ta dll est au même endroit que l'application java ?

    A+
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Membre confirmé
    Inscrit en
    Novembre 2007
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 106
    Par défaut
    J'ai abandonné le serveur et je fais une exécution locale mais j'ai toujours cette erreur:
    Exception in thread "main" java.lang.UnsatisfiedLinkError: coucou
    at .....Test.coucou(Native Method)
    Oui ma classe est dans un package.
    Ma DLL elle est dans le dossier System32 de Windows.

  5. #5
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Essaye
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    System.loadLibrary("c:/windows/system32/nomDLL");
    ou
    System.loadLibrary("c:/windows/system32/nomDLL.dll");
    ou
    System.loadLibrary("c:\\windows\\system32\\nomDLL");
    ou
    System.loadLibrary("c:\\windows\\system32\\nomDLL.dll");
    A+
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Non la librairie semble bien chargé, sinon tu aurais eu une erreur du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Exception in thread "main" java.lang.UnsatisfiedLinkError: no Projet in java.library.path

    Ici on dirait plutôt que c'est la fonction native qui n'est pas trouvé...

    Il faudrait donc voir comment tu génères ta DLL, sachant que l'API Win32 utilisé des formats d'appels de méthodes stdcall incompatible avec JNI...

    Essayes de compiler la DLL avec les options --add-stdcall-alias ou -Wl,--kill-at si tu utilises gcc...

    Sinon il faut voir la doc de ton compilateur natif...


    a++

  7. #7
    Membre confirmé
    Inscrit en
    Novembre 2007
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 106
    Par défaut
    Oui, je pense qu'il ne trouve pas la méthode de la DLL.

    Mon but est d'utiliser une DLL "rapi.dll" installée par ActivSync mais il m'affiche la même erreur.
    Pour cela, j'ai préféré commencer avec un exemple simple en créant moi-même la DLL.
    La DLL, je l'ai créé avec Visual C++ et j'ai toujours la même erreur.

    Je ne sais pas comment résoudre ce problème.

  8. #8
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Il faudrait donc voir comment tu génères ta DLL, sachant que l'API Win32 utilisé des formats d'appels de méthodes stdcall incompatible avec JNI...
    Tu veux dire qu'on ne peut pas faire de JNI avec windows ?
    On l'a pourtant fait...

    D'où viens le problème selon toi ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #9
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par OButterlin Voir le message
    Tu veux dire qu'on ne peut pas faire de JNI avec windows ?
    On l'a pourtant fait...
    Non non : je veux juste dire que Windows utilises plusieurs normes pour nommer et appeler les fonctions. Et l'une d'entre elle (stdcall) modifie en fait le nom de la fonction dans la DLL, ce qui fait que la JVM ne la retrouve pas...

    Les options ci-dessus permettent de modifier cela avec gcc... par contre avec Visual C++ je n'ai aucune idée des options à utiliser...



    air75 tu pourrais peut-être te tourner vers JNA pour utiliser directement la librairie rapi.dll :
    http://blog.developpez.com/index.php...&c=1&tb=1&pb=1

    a++

  10. #10
    Membre confirmé
    Inscrit en
    Novembre 2007
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 106
    Par défaut
    J'ai l'impression qu'il charge bien la DLL mais à l'exécution, il ne la trouve pas.

    Je ne sais qu'est ce qu'il manque.

    Je ne connais pas JNA. Tu crois qu'on peut utiliser directement les méthodes définies dans la librairie rapi.dll, sans écrire nous-même une autre DLL ?
    Merci

  11. #11
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Non non : je veux juste dire que Windows utilises plusieurs normes pour nommer et appeler les fonctions. Et l'une d'entre elle (stdcall) modifie en fait le nom de la fonction dans la DLL, ce qui fait que la JVM ne la retrouve pas...

    Les options ci-dessus permettent de modifier cela avec gcc... par contre avec Visual C++ je n'ai aucune idée des options à utiliser...
    ah ok, merci pour la précision...

    Il est vrai qu'on avait créé la dll nous même, mais de mémoire, on l'avait placé au même endroit que le jar de l'application...
    (air75 : Si tu peux faire ce test, à tout hasard)

    A+
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  12. #12
    Membre confirmé
    Inscrit en
    Novembre 2007
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 106
    Par défaut
    Oui cette DLL je l'ai créé moi-même mais même avec rapi.dll (que je n'ai pas créé) qui est installé automatiquement par ActivSync, j'ai toujours la même erreur.

    Sinon, j'ai essayé d'utiliser JNA au lieu de JNI, pour faire plus simple mais j'ai toujours cette erreur.
    java.lang.UnsatisfiedLinkError: Cannot locate function 'coucou'
    'coucou' c'est une méthode définie dans ma DLL.

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

    Merci

  13. #13
    Membre confirmé
    Inscrit en
    Novembre 2007
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 106
    Par défaut
    Je suis arrivé à charger ma DLL (rapi.dll) sans erreur avec la librairie JNA (c'est plus simple que passer par JNI, il n y a pas de code en C à taper).

    J'ai définis une interface JNADemo.java :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    import com.sun.jna.Library;
    public interface JNADemo  extends  Library
    {
       public int  CeRapiInit();
       public boolean CeCopyFile(String src,String dest,boolean etat);
    }
    Les méthodes sont appelées à partir du programme Java:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      String src ="C:\\doc_pda\\fichier.txt";
      String dest = "\\My Documents\\Business\\fichier.txt";
      JNADemo demo = (JNADemo) Native.loadLibrary("rapi", JNADemo.class);
     
      a = demo.CeRapiInit();
      copi =  demo.CeCopyFile(src,dest,false);
    Par contre, je n'arrive pas à copier le fichier entre le PDA et le PC.
    J'ai toujours copi à false.

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

    Merci

  14. #14
    Membre confirmé
    Inscrit en
    Novembre 2007
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 106
    Par défaut
    Salut,

    Je charge bien la dll (rapi.dll) mais je n'arrive pas à utiliser la méthode CeCopyFile() de cette dll. Elle me retourne toujours false ce qui veut dire que l’opération n'est pas effectuée.

    Est-ce que quelqu'un à une réponse pour ce problème ?

    Voilà mon code.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    String src ="C:\\doc_pda\\fichier.txt";
    String code_src = new String(src.getBytes("UTF-8"), "ISO8859_1");
    String dest = "\\java\\fichier.txt";String code_dest = new String(dest.getBytes("UTF-8"), "ISO8859_1");
    JNADemo demo = (JNADemo) Native.loadLibrary("rapi", JNADemo.class);
    a = demo.CeRapiInit();
    copi =  demo.CeCopyFile(code_src,code_dest,false);

  15. #15
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Puisque la méthode te retourne une valeur cela signifie qu'elle est bien appelé, donc le problème vient soit des paramètres que tu lui passes, soit du code de cette méthode...


    a++

    PS : Au passage le code suivant ne donnera rien de bon si ta chaine est correctement formé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    new String(src.getBytes("UTF-8"), "ISO8859_1")

  16. #16
    Membre confirmé
    Inscrit en
    Novembre 2007
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 106
    Par défaut
    Bonjour,

    Je me permets de renouveler mon problème car je ne trouve pas de solution.

    J’essaye de copier un fichier du PDA vers le PC. J’utilise la librairie rapi.dll via la JNA.
    La liaison est faite avec un câble USB.
    Une fois la librairie rapi.dll chargée, j’appelle la méthode CeRapiInit() pour initialiser la connexion. Puis j’appelle la méthode CeCopyFile pour copier le fichier.

    Mon problème est qu'après l’exécution du programme, la méthode CeRapiInit() me retourne 0 (je ne sais pas si la connexion est faite ou pas), sachant que si je débranche le câble USB et que j’exécute le programme, celui-ci se bloque jusqu'au rebranchement du câble. Ce qui signifie qu’il détecte bien le câble.

    Est-ce que quelqu’un a une idée ?
    Merci pour votre aide
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      Rapi demo = (Rapi) Native.loadLibrary("rapi", Rapi.class);
      a = demo.CeRapiInit();
       copi =  demo.CeCopyFile("C:\\doc_pda\\fichier.txt","My Documents\\Business\\fichier.txt",false) ;
    Sinon, j’ai une autre question

    La méthode CeRapiUninit () retourne une constante de type HRESULT
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    HRESULT CeRapiInit ();
    E_SUCCESS indicates success. CERAPI_E_ALREADYINITIALIZED indicates that RAPI has already been initialized. E_FAIL indicates failure.
    En java : dans l’interface Rapi.java. Je définis le type de retour de cette méthode comme un int.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public int CeRapiInit();
    Est-ce que c'est bon?

    Merci pour votre aide

  17. #17
    Membre averti
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 21
    Par défaut
    Bonjour,

    Je suis dans le même cas que toi actuellement si tu trouves une solution, je suis preneur.
    Impossible de mettre un fichier sur un PDA grâce à java.

Discussions similaires

  1. "Dé-surcharger" une méthode native javascript
    Par Takezo1584 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 26/08/2007, 12h37
  2. [JNI] Time out sur méthode native
    Par pierre2006 dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 17/11/2006, 11h44
  3. [JNI] Java ne trouve pas mes méthodes natives
    Par carotte31 dans le forum Entrée/Sortie
    Réponses: 5
    Dernier message: 14/06/2006, 21h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo