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

C++ Discussion :

passage de parametre java vers c++ JNI


Sujet :

C++

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

    Je cherche a récupérer un paramètre d'une méthode java pour pouvoir l'utiliser ensuite dans d'autre fonction C++.

    j'arrive déjà a exécuter des méthodes java depuis le c++ grâce à JNI avec la création d'une JVM que j'ai mis dans une fonction . Or je ne sais comment récupérer ses paramètres.

    Il semblerait qu'il faille utiliser :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    extern "C" JNIEXPORT void JNICALL Java_UseObjects_changeObject( JNIEnv* env, jobject, jobject obj)
    {
        jclass clas = env->GetObjectClass(obj);
     
        jfieldID fid = env->GetFieldID(clas, "variable java", "I");
     
        jmethodID mid = env->GetMethodID(clas, "methode java", "()V");
        int value = env->GetIntField(obj, fid);
    }
    mais je pige pas tres bien son utilisation:
    est ce qu'il faut l'ajouter en plus de la fonction de la creation de la JVM? Dans ce cas l'appeler apres?
    Et à quoi correspond la variable jobject obj ?

    l'ideal est que je puisse recuperer un tableau et la j'ai lu sur un post
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    jstring jstr = (jstring)env->GetObjectArrayElement(string, i);
    Les utilisateurs de JNI se sont surement déjà posés la question et je suis un peu embrouillé

    Si qqun a une idée

    [EDIT]
    il semblerait que la méthode suscité permet d'appeler des méthodes et variables C++ vers java.

    Or je veux l'inverse

    Snif personne a un petit indice

    merci

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2006
    Messages : 107
    Par défaut
    Je cherche a récupérer un paramètre d'une méthode java pour pouvoir l'utiliser ensuite dans d'autre fonction C++.
    J'avais eu à faire ça il y a un an ou deux..
    Je te passe ce que j'avais fais :

    Voila la classe étudiant.java :
    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
     
    public class Etudiant{
    static{
    	System.loadLibrary("essai");
    	}
     
    String nom;
    int notes[];
    int nbNotes;
     
     
    Etudiant(){
    	notes=new int[10];
    	nbNotes=0;
    	nom="ROGER !";
    }
     
    /* les fonctions natives implémentées en C */
    native void message();
    native void message(String cl);
    native void message(java.util.Date date);
    native void classement(int x);
    native boolean addNote(int note);
    native void afficherNotes();
    native void afficherMoyenne();
     
    double getMoyenne(){
    	if (nbNotes<=0) return -1;
    	int somme=0;
    	for (int i=0; i<10; i++) somme+=notes[i];
    	return (double)(somme)/(double)(nbNotes); 
    }
     
     
    public static void main(String args[]){
    	Etudiant d= new Etudiant();
    	d.message();
    	d.classement(14);
    	d.message("de test de JNI !");
    	d.message(java.sql.Date.valueOf("2008-05-27") );
    	System.out.println("Mettre la premiere note à 14 : "+d.addNote(14));
    	d.afficherNotes();
    	System.out.println("Mettre la seconde note à 16 : "+d.addNote(16));
    	d.afficherNotes();
    	d.nbNotes=10;
    	System.out.println("Mettre la 10ieme note à 15 : "+d.addNote(15));
    	d.afficherNotes();
    	d.nbNotes=2;
    	d.afficherMoyenne();
    }
     
     
    }
    Les méthodes sont déclarées natives pour dire qu'elles sont implémentées en C.

    Voila le header étudiant.h, généré automatiquement par la commande javah -jni :
    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
    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class Etudiant */
     
    #ifndef _Included_Etudiant
    #define _Included_Etudiant
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     Etudiant
     * Method:    message
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_Etudiant_message__
      (JNIEnv *, jobject);
     
    /*
     * Class:     Etudiant
     * Method:    message
     * Signature: (Ljava/lang/String;)V
     */
    JNIEXPORT void JNICALL Java_Etudiant_message__Ljava_lang_String_2
      (JNIEnv *, jobject, jstring);
     
    /*
     * Class:     Etudiant
     * Method:    message
     * Signature: (Ljava/util/Date;)V
     */
    JNIEXPORT void JNICALL Java_Etudiant_message__Ljava_util_Date_2
      (JNIEnv *, jobject, jobject);
     
    /*
     * Class:     Etudiant
     * Method:    classement
     * Signature: (I)V
     */
    JNIEXPORT void JNICALL Java_Etudiant_classement
      (JNIEnv *, jobject, jint);
     
    /*
     * Class:     Etudiant
     * Method:    addNote
     * Signature: (I)Z
     */
    JNIEXPORT jboolean JNICALL Java_Etudiant_addNote
      (JNIEnv *, jobject, jint);
     
    /*
     * Class:     Etudiant
     * Method:    afficherNotes
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_Etudiant_afficherNotes
      (JNIEnv *, jobject);
     
    /*
     * Class:     Etudiant
     * Method:    afficherMoyenne
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_Etudiant_afficherMoyenne
      (JNIEnv *, jobject);
     
    #ifdef __cplusplus
    }
    #endif
    #endif
    Voila le fichier C qui implémente les méthodes déclarées dans la classe étudiant.java :
    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
    #include "Etudiant.h"
    #include <stdio.h>
     
     
    /*
    code de : native void message();
    La fonction doit afficher "etudiant".
    */
    JNIEXPORT void JNICALL Java_Etudiant_message__ (JNIEnv *env, 
    						jobject obj){
      printf("etudiant\n");
      /*eviter le warning du compilo qui di qu'on n'utilise pas les paramaetres :*/
      (void)env;
      (void) obj;
    }
     
     
     
    /*
    code de : native void message(String cl);
    La fonction doit afficher "etuidant de la class -cl-" 
    avec cl la chaine de carac passé en param.
    */
    JNIEXPORT void JNICALL Java_Etudiant_message__Ljava_lang_String_2(JNIEnv *env, 
    						jobject obj, jstring msgJava){
      /*on convertie la chaine :*/
      const char *msg = (*env)->GetStringUTFChars(env,msgJava,0);
      printf("etudiant de la classe %s\n",msg);
      /*on averti le garbage collector :*/
      (*env)->ReleaseStringUTFChars(env, msgJava, msg);
      /*eviter le warning du compilo qui di qu'on n'utilise pas les paramaetres :*/
      (void) obj;
    }
     
     
     
    /*
    code de : native void classement(int x);
    La fonction doit afficher "x-ième étudiant"
    avec x la valeur passé en param.
    */
    JNIEXPORT void JNICALL Java_Etudiant_classement(JNIEnv *env,
    				 jobject obj, jint nb){		 
      printf("%i-ième etudiant\n",nb);	
      /*eviter le warning du compilo qui di qu'on n'utilise pas les paramaetres :*/
      (void)env;
      (void) obj;		 
    }
     
     
     
    /*
    code de : native void message(java.util.Date date);
    La fonction doit afficher "Relevé du -date- : étudiant -nom-"
    Avec date la date passée en param et nom le nom de l'étudiant.
    */
    JNIEXPORT void JNICALL Java_Etudiant_message__Ljava_util_Date_2(JNIEnv *env, jobject obj, 
    								jobject date){
      	/*----------------------LA DATE----------------------
    	/on récupere l'identifiant de la méthode toString de la classe date*/
    	jmethodID id= (*env)->GetMethodID(env, (*env)->GetObjectClass(env, date), "toString", "()Ljava/lang/String;" );
    	/*on appel la méthode :*/
    	jstring chaine= (jstring) (*env)->CallObjectMethod(env, date, id);
    	/*on convertie la chaine :*/
      	const char *msg = (*env)->GetStringUTFChars(env,chaine,0);
      	/*---------------LE NOM DE LETUDIANT :---------------*/
      	/*on récup l'identifiant de l'attribut*/
    	jfieldID idnom= (*env)->GetFieldID(env, (*env)->GetObjectClass(env,obj), "nom", "Ljava/lang/String;");
    	/*on accede à l'attribut :*/
    	jstring nomEtu = (*env)->GetObjectField(env, obj, idnom) ;
    	/*on le converti aussi :*/
    	const char *nomEtudiant = (*env)->GetStringUTFChars(env,nomEtu,0);
    	/*----------------OK------------------------------------*/
      	printf("Relevé du %s : étudiant %s\n",msg,nomEtudiant);
      	/*on averti le GC qu'il peut désalloué :*/
      	(*env)->ReleaseStringUTFChars(env, chaine, msg);
      	(*env)->ReleaseStringUTFChars(env, nomEtu, nomEtudiant);
    }
     
     
     
    /*
    code de : native boolean addNote(int note);
    La fonction doit ajouter la note fournie en param s'il y a 
    moins de 10 notes deja rentrées. Retourne true ou false si 
    elle a pu ajouter la note ou pas.
    */
    JNIEXPORT jboolean JNICALL Java_Etudiant_addNote(JNIEnv *env, jobject obj, jint note){
    	/*----------------------LE NB DE NOTE DE LETUDIANT :----------------------*/
    	/*on récup l'identifiant de l'attribut */
    	jfieldID idNbNotes= (*env)->GetFieldID(env, (*env)->GetObjectClass(env,obj), "nbNotes","I");
    	/*on accede à l'attribut :*/
    	jint nbNotes = (*env)->GetIntField(env, obj, idNbNotes) ;
    	if (nbNotes<10){
    		/*----------------------ACCES AU TABLEAU DE NOTES :----------------------*/
    		/*on récup l'identifiant de l'attribut*/
    		jfieldID idTab= (*env)->GetFieldID(env, (*env)->GetObjectClass(env,obj), "notes", "[I");
    		/*on accede à l'attribut :*/
    		jintArray tab = (*env)->GetObjectField(env, obj, idTab) ;
    		/*on recup le pointeur sur le tableau :*/
    		jint *tabNote=(*env)->GetIntArrayElements(env, tab, 0);
    		/*on insere la note dans le tableau*/
    		tabNote[nbNotes]=note;
    		/*on incrémente le nb de notes :*/
    		(*env)->SetIntField(env, obj, idNbNotes, nbNotes+1);
    		/*on dit au GC qu'il peut désalloué ET qu'il doit synchroniser le tableau :
    		 le dernier param : jint mode à 0 : libère et met à jour*/
    		(*env)->ReleaseIntArrayElements(env, tab, tabNote, 0);
    		return JNI_TRUE;
    	}
    	return JNI_FALSE;
    }		
     
     
    /*
    code de : native void afficherNotes();
    La fonction afficher le tableau de note.
    */
    JNIEXPORT void JNICALL Java_Etudiant_afficherNotes(JNIEnv *env, jobject obj){
    	/*----------------------ACCES AU TABLEAU DE NOTES :----------------------*/
    	/*on récup l'identifiant de l'attribut*/
    	jfieldID idTab= (*env)->GetFieldID(env, (*env)->GetObjectClass(env,obj), "notes", "[I");
    	/*on accede à l'attribut :*/
    	jintArray tab = (*env)->GetObjectField(env, obj, idTab) ;
    	/*on récupère sa taille :*/
    	jint l= (*env)->GetArrayLength(env, tab);
    	/*on recup le pointeur sur le tableau :*/
    	jboolean myBool=JNI_FALSE;
    	jint *tabNote=(*env)->GetIntArrayElements(env, tab, &myBool);
    	/*on affiche :*/
    	int i;
    	for (i=0; i<l; i++) printf("%i ",tabNote[i]);
    	printf("\n");
    	/*on dit au GC qu'il peut désalloué et qu'il n'a pas besoin de synchroniser :
    	 le dernier param : jint mode à JNI_ABORT : libère et ne met pas à jour*/
    	(*env)->ReleaseIntArrayElements(env, tab, tabNote, JNI_ABORT);
    }
     
     
    /*
    code de : native void afficherMoyenne();
    La fonction affiche le message "Moyenne de l'étudiant -nom- = -moyenne-"
    avec nom le nom de l'étudiant et moyenne sa moyenne obtenue en 
    appelant la méthode java pure getMoyenne().
    Renvoit true si tout se passe bien, false sinon.
    */
    JNIEXPORT void JNICALL Java_Etudiant_afficherMoyenne(JNIEnv *env, jobject obj){
    	/*---------------LE NOM DE LETUDIANT :---------------*/
      	/*on récup l'identifiant de l'attribut*/
    	jfieldID idnom= (*env)->GetFieldID(env, (*env)->GetObjectClass(env,obj), "nom", "Ljava/lang/String;");
    	/*on accede à l'attribut :*/
    	jstring nomEtu = (*env)->GetObjectField(env, obj, idnom) ;
    	/*on le converti aussi :*/
    	const char *nomEtudiant = (*env)->GetStringUTFChars(env,nomEtu,0);
    	/*----------------------LE NB DE NOTE DE LETUDIANT :----------------------*/
    	/*on récup l'identifiant de l'attribut */
    	jfieldID idNbNotes= (*env)->GetFieldID(env, (*env)->GetObjectClass(env,obj), "nbNotes","I");
    	/*on accede à l'attribut :*/
    	jint nbNotes = (*env)->GetIntField(env, obj, idNbNotes) ;
    	/*----------------LA MOYENNE : ------------------------*/
    	/*on récupere l'identifiant de la méthode getMoyenne :*/
    	jmethodID id= (*env)->GetMethodID(env, (*env)->GetObjectClass(env, obj), "getMoyenne", "()D" );
    	/*on appel la méthode :*/
    	jdouble moy=  (*env)->CallDoubleMethod(env, obj, id);
    	/*----------------OK------------------------------------*/
    	printf("L'étudiant %s a %i notes. Sa Moyenne est de %.2f.\n",nomEtudiant,nbNotes,  moy);
    	(*env)->ReleaseStringUTFChars(env, nomEtu, nomEtudiant);
    }
    Honnêtement je ne me rapel plus comment ça marchait, mais j'avais bien commenté.

    J'avais fais également un petit makefile, je te le donne tel quel :
    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
     
    #makefile pour utilisation de jni
    #ecrit par Pesle Adrien
     
    FICHIER_JAVA=Etudiant.java
    FICHIER_C=Etudiant.c
    NOM_LIBRAIRIE=libessai.so
     
     
     
    CLASSE=$(subst .java,,$(FICHIER_JAVA))
    FICH_POINT_O=$(subst .c,.o,$(FICHIER_C))
     
    all: affichePath compileJava genere_point_h compileC creerLib test
     
     
    affichePath:
    	@echo LD_LIBRARY_PATH=$(LD_LIBRARY_PATH);
    	@echo JAVA_HOME=$(JAVA_HOME); 
    	@echo "";
     
    compileJava :
    	javac $(FICHIER_JAVA)
     
    genere_point_h:
    	javah -jni $(CLASSE)
     
    compileC:
    	gcc -Wall -Wextra -Werror -c -fPIC -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux $(FICHIER_C)
     
    creerLib :
    	gcc -shared -o $(NOM_LIBRAIRIE) $(FICH_POINT_O)
     
    test:
    	@echo "\n\n";
    	@echo "\tTEST : \n";
    	@java $(CLASSE)
     
     
    clean:
    	rm *.o 
    	rm $(CLASSE).class
    	find . -name "$(NOM_LIBRAIRIE)" -print0 | xargs -0 rm 
    	#nettoi les fichiers généré lorsque sa plante :
    	find . -name "hs_err_*" -print0 | xargs -0 rm

Discussions similaires

  1. Passage de parametre java vers c++ JNI
    Par ti_angelo dans le forum Entrée/Sortie
    Réponses: 0
    Dernier message: 28/04/2009, 17h20
  2. Passage de parametre Servlet vers JSP
    Par Ahmed0012 dans le forum Servlets/JSP
    Réponses: 8
    Dernier message: 11/05/2006, 18h27
  3. Passage de parametre Access vers Excel
    Par climz dans le forum Access
    Réponses: 2
    Dernier message: 05/05/2006, 15h07
  4. Réponses: 2
    Dernier message: 24/03/2005, 10h20
  5. [VB.NET] Passage de parametres à une Applet Java
    Par AntiSAL dans le forum ASP.NET
    Réponses: 4
    Dernier message: 18/08/2004, 11h04

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