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

Entrée/Sortie Java Discussion :

JNA ou meme JNI peu importe


Sujet :

Entrée/Sortie Java

  1. #1
    Membre du Club
    Inscrit en
    Novembre 2008
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 9
    Par défaut JNA ou meme JNI peu importe
    Bonjour, je voulais savoir si il etait possible de creer une classe/fonction Java qui puisse etre utilisable/appellee par un programme C/C++ et non l'inverse comme il est bien souvent explique sur les sites dedies a JNI/JNA.
    En gros Excecuter du code Java en C.
    si oui, pourriez vous m'eclairer sur la methode a suivre.
    Merci

    Benco

  2. #2
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    http://www.javaworld.com/javaworld/j...javatip17.html

    Gros tuto sur JNI, dont une partie qui décrit la façon de procéder pour appeler du code java depuis du code c++ (et donc par extension depuis du code c)

  3. #3
    Membre du Club
    Inscrit en
    Novembre 2008
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 9
    Par défaut
    Merci pour le lien,
    le probleme c'est que je n'ai jamais fait de JNI, et je trouve l'exemple un peu complique. ce que je voudrais faire est tres simple a partir d'un programme c++
    appeler une fonction java avec des arguments et que cette fonction retourne une valeur (int, bool).
    j'ai trouve un exemple plus simple a l'adresse http://www.iut-orsay.fr/dptinfo/Peda...a/javaJni.html, j'arrive a compiler creer la DLL mais je n'arrive pas a utiliser la fonction de la DLL :
    l'exemple que j'ai repris est la partie "Utilisation de champs ou méthodes d'un objet".
    j'ai un probleme lors de l'utilisation de la methode, je n'arrive pas a creer la machine virtuelle avec la fonction JNI_CreateJavaVM

    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
     
    JavaVM * jvm;
        JNIEnv *env;
        JavaVMInitArgs vm_args;
     
     
     
    	JavaVMOption options[4];
        JNI_GetDefaultJavaVMInitArgs(&vm_args);
     
    	options[0].optionString = "-Djava.compiler=NONE";
    	options[1].optionString = "-Djava.class.path=C:\Java_workspace\test\src";
    	options[2].optionString = "-Djava.class.path=C:\Java_workspace\test\src";
        options[3].optionString = "-verbose:jni";
     
    	vm_args.version = JNI_VERSION_1_6;
    	vm_args.options = options;
    	vm_args.nOptions =4;
    	vm_args.ignoreUnrecognized = FALSE;//TRUE
     
     
     
        int ret = JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);
    et avec ce code au niveau de NI_CreateJavaVM jai une erreur memoire qui se cree a l'execution.
    Mise a part cela, n'y aurait-il pas des exemple en JNA(C++ utilisant Java)vu que c'est plus simple.
    Merci
    Ben.

  4. #4
    Membre du Club
    Inscrit en
    Novembre 2008
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 9
    Par défaut
    J'ai trouve, apparement c'etait un probleme de DLL, il faut mettre la dll jvm.dll du dossier java dans le rep courant du projet et creer la lib a partir de cette dll.
    J'ai maintenant un nouveau probleme, c'est que la fonction JNI_CreateJavaVM me renvoie tout le temps -1.
    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
    JavaVM * jvm;
            JNIEnv *env;  
            JavaVMInitArgs vm_args;
     
    	//memset(&vm_args, 0, sizeof(vm_args));
            JavaVMOption options;
            options.optionString = "-Djava.class.path=C:\\func\\lop";
    	vm_args.version = JNI_VERSION_1_6;
            JNI_GetDefaultJavaVMInitArgs(&vm_args);
     
            vm_args.nOptions = 1;
            vm_args.options = &options;
            vm_args.ignoreUnrecognized = TRUE;
     
            ret = JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);
    	if(ret < 0)
                    ShowMessage("\nUnable to Launch JVM\n");
            jclass i_cls;
            i_cls = env->FindClass("UtilObj");
            if (i_cls == 0) {
                    ShowMessage("unable to find class");
                    exit(2);
            }
    Quelqun aurait-il une idee?

  5. #5
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    En fait il faut laisser la dll jvm.dll à son endroit initial et bien configurer le path d'inclusion des librairies au moment où tu crées ton projet c++.

    Car la dll dépend de toutes les autre librairies java, donc voilà, faut pas y toucher elle est bien où elle est .

    Ainsi que penser au java.library.path

  6. #6
    Membre du Club
    Inscrit en
    Novembre 2008
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 9
    Par défaut
    Citation Envoyé par sinok Voir le message
    En fait il faut laisser la dll jvm.dll à son endroit initial et bien configurer le path d'inclusion des librairies au moment où tu crées ton projet c++.

    Car la dll dépend de toutes les autre librairies java, donc voilà, faut pas y toucher elle est bien où elle est .

    Ainsi que penser au java.library.path
    Bravos!
    en meme temps c'est logique
    maintenant, j'ai la methode FindClass qui me retourne une valeur null, le chemin est pourtant bon, j'ai meme essaye".-D.java.class.path=." rien y fait!

  7. #7
    Membre du Club
    Inscrit en
    Novembre 2008
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 9
    Par défaut
    apparemment il y avait une ligne qui n'allait pas dans le fichier java
    System.loadlibrary("Util.h"), j'avais oublie de l'enlever

    sinon j'ai une question (que je repondrai surment par moi meme) :
    est il possible d'appeler une methode java et de recuperer une valueur de retour
    exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    i_mth = env->GetStaticMethodID(i_cls, "main", "([Ljava/lang/String;)I");
    jint Var = env->CallStaticVoidMethod(i_cls, i_mth);
    ??
    Merci

  8. #8
    Membre du Club
    Inscrit en
    Novembre 2008
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 9
    Par défaut
    Oui on peut et avec des arguments
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    jclass i_cls;               // identite' de la classe
    jmethodID i_mth;            // identite' de la me'thode
    jstring j_ch;               // pour cre'er une chai^ne 'java'
    jint val
    i_cls = env->FindClass("Myclass");//on cherche la classe java
    i_mth = env->GetStaticMethodID(i_cls, "returnInt", "(Ljava/lang/String;)I"); //on recupere la methode
     
    j_ch = env->NewStringUTF(" depuis C++ !");
    val = env->CallStaticIntMethod(i_cls, i_mth,j_ch);//on appelle la methode
    code de la fonction java
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public static int returnInt(String SS) {
    		return 10;
       }
    autre question :
    est il possible de voir ce qu'il se passe en interne dans les classe java par des System.out.println qui pourait etre visible
    il y a une methode : c'est d'ecrire dans des fichiers et visualiser le fichier apres l'appel de la procedure, mais n'y a t'il pas plus simple?.
    Merci sinok!, merci moi!

    si jamais je trouve le temps, je ferai un petit tuto, comme c'est pas vraiment claire sur le net

  9. #9
    Membre du Club
    Inscrit en
    Novembre 2008
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 9
    Par défaut
    Rebonjour la Jeunesse c'est encore moi!
    j'ai un petit probleme pour appeler la classe java maintenant.
    En fait celle ci utilise la librairie jdom pour creer des fichier XML. donc quand j'appelle une classe java qui n'utilise pas jdom ca marche : elle est trouvee, mais si j'appelle une classe qui utilise jdom, la classe n'est pas trouvee, jai bien inclu la librairie jdom.jar dans le dossier courant du projet c++ mais rien y fait.

    si quelqu'un pouvait m'aider ou juste me guider ce serait magnifique
    MERCI

  10. #10
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Bah celà vient probablement du fait que tu ne configures pas ton classpath. ET que donc java ne trouve pas ta librairie

    l'opion de la ligne de commande pour préciser le classpath est -cp

  11. #11
    Membre du Club
    Inscrit en
    Novembre 2008
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 9
    Par défaut Jbosse un samedi, c'est vraiment la classe:(
    Yo Merci Sinok, je me doutait bien que c'etait cela. Le probleme etait que je ne savais pas comment le specifier dans les options.
    J'ai trouve
    en fait au depart j'avais essaye cela avant de poster
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    JavaVMOption options[2];
            options[0].optionString = "-Djava.class.path=C:\\func\\lop";//pour la classe java
            options[1].optionString = "-Djava.library.path=C:\\func\\lop.jdom.jar";//pour le jar
     
    	vm_args.version = JNI_VERSION_1_6;
            JNI_GetDefaultJavaVMInitArgs(&vm_args);
     
            vm_args.nOptions = 2;
            vm_args.options = &options;
            vm_args.ignoreUnrecognized = TRUE;
    et bien en fait non ce n'etait pas ca,
    voila la solution
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    JavaVMOption options[1];
            options[0].optionString = "-Djava.class.path=C:\\func\\lop;C:\\func\\lop\\jdom.jar";//pour la classe java et pour le jar
     
    	vm_args.version = JNI_VERSION_1_6;
            JNI_GetDefaultJavaVMInitArgs(&vm_args);
     
            vm_args.nOptions = 1;
          vm_args.options = &options;
            vm_args.ignoreUnrecognized = TRUE;
    il faut donc donner le chemin de la lib dans la meme option avec le chemin entier
    et voila voilaaa!! c'est pret, A table!!
    Arigatou!

  12. #12
    Membre averti
    Inscrit en
    Novembre 2008
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 12
    Par défaut
    Bonjour,

    Je voudrai savoir quel est la ligne de commande que vous utilisez pour compiler sous windows

    Merci

  13. #13
    Membre averti
    Inscrit en
    Novembre 2008
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 12
    Par défaut
    j'ai reussi à compiler avec :
    gcc -I"<javahome>\include" -I"<javahome>\include\win32" FichierMain.c "<javahome>\lib\jvm.lib"

    Mon fichier java est Fichier.java avec une methode public void setAttribut(String msg);

    mon code compile et s'execute jusqu'a l'appel de la methode :
    (*penv)->CallVoidMethod(penv, i_cls, i_mth, j_ch);


    Voici le code en entier :
    Code C : 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
     
    #include <stdio.h>
    #include <jni.h>
    #include <stdlib.h>
     
    #define USER_CLASSPATH "D:\\eclipse\\workspace\\TEST\\wrapperCtoJava\\src"
     
     
    int main(int nm, char * tm[])
    {    
        JNIEnv *penv;
        JavaVM *jvm;
        JavaVMInitArgs vm_args;
        jint res;
        jclass i_cls;               // identité de la classe
        jmethodID i_mth;            // identité de la méthode
        jstring j_ch;               // pour créer une chaîne 'java'
        JavaVMOption options[1];
     
        options[0].optionString = "-Djava.class.path=" USER_CLASSPATH;
     
        vm_args.version = JNI_VERSION_1_4;
        vm_args.options = options;
        vm_args.nOptions = 1;
        vm_args.ignoreUnrecognized = JNI_TRUE;
     
     
        /* Créer la machine virtuelle Java */
        printf("Creation Java Virtual Machine \n");
        res = JNI_CreateJavaVM(&jvm,(void **)&penv,&vm_args);
        if (res < 0) {
            fprintf(stderr, "Machine virtuelle non démarée !!!\n");
            exit(1);
        }
            printf("Result of JVM : %i \n", res);
     
     
        // Récupérer la classe
        printf("Find Class : Fichier \n");
        i_cls = (*penv)->FindClass(penv,"Fichier");
        if (i_cls == NULL) {
               fprintf(stderr, "Class not found\n");
               goto destroy;
           }
            printf("Result of Classe : %i \n", i_cls);
     
     
        // Récupérer la méthode
        printf("Get Method : setAttribut \n"); 
        i_mth = (*penv)->GetMethodID(penv, i_cls, "setAttribut", "(Ljava/lang/String;)V");
        if (i_mth == NULL) {
               fprintf(stderr, "Methode Fichier.setAttribut not found\n");
               goto destroy;
           }
           printf("Result of Method : %i \n", i_mth);
     
     
           printf("Creation String \n");
           j_ch = (*penv)->NewStringUTF(penv, "[C] blabla ");
        if (j_ch == NULL) {
               fprintf(stderr, "End of memory !!!\n");
               goto destroy;
           }
            printf("Result of creation Srting : %i \n",j_ch);
     
     
           printf("Call Method \n");
           (*penv)->CallVoidMethod(penv, i_cls, i_mth, j_ch);
     
        destroy:
                    if ((*penv)->ExceptionOccurred(penv)) {
                       (*penv)->ExceptionDescribe(penv);
                       }
     
         printf("Destruction Java Virtual Machine \n");
         (*jvm)->DestroyJavaVM(jvm);
     
    }



    A l'execution du programme, aumoment de lancer la methode,le prog plante et windows me sort :
    a.exe a rencontré un problème et doit fermer. Nous vous prions de nous excuser pour le désagrément encouru.

    Est ce que qq un a une idée ??

    Merci

  14. #14
    Membre du Club
    Inscrit en
    Novembre 2008
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 9
    Par défaut
    salut!
    ton callvoidmethod a trop d'argument je pense: il faut lui donner un objet de la classe et la methode i_mth
    ++

  15. #15
    Membre averti
    Inscrit en
    Novembre 2008
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 12
    Par défaut
    en fait j'ai rajouté :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     
    printf("\n Creation of Tab String \n");
            stringClass = (*penv)->FindClass(penv, "java/lang/String");
            args = (*penv)->NewObject(penv, stringClass, i_mth, j_ch);
            if (args == NULL) {
                 goto destroy;
            }
            printf("Result of creation arguments : %i \n", args);

    la methode NewObject fait appel à CallMethod et tout marche bien ! du coup je ne marque plus le code (*penv)->CallVoidMethod(...) qui fait planter !!

    Merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Toutes versions] Fichier vierge qui execute la meme macro peu importe le fichier selectionne
    Par yaya.gaga dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 10/10/2014, 22h54
  2. Réponses: 1
    Dernier message: 30/06/2008, 14h26
  3. [MySQL] Peu importe la taille du tableau, SQL est censé tout enregistrer(non pas foreach :D )
    Par Dermiste dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 26/04/2008, 02h47
  4. Réponses: 4
    Dernier message: 28/10/2007, 21h01
  5. [Peu important]JTable effacer colonne
    Par leminipouce dans le forum Composants
    Réponses: 6
    Dernier message: 07/12/2005, 18h30

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