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 :

C++ et JNI : Pointeur et m�thodes Callback


Sujet :

C++

  1. #1
    Membre exp�riment�
    Avatar de giminik
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    303
    D�tails du profil
    Informations personnelles :
    �ge : 43
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 303
    Par d�faut C++ et JNI : Pointeur et m�thodes Callback
    Bonjour,

    Le probl�me dont je vais vous parler doit �tre c�t� C++ et non Java JNI.
    Nous tentons d'intercepter des �v�nements windows via les hooks, et de remonter ces �v�nements � Java via JNI.

    Nous arrivons bien � d�tecter les �v�nement gr�ce aux hooks. Pour communiquer avec Java, nous disposons d'un pointeur vers la JVM Java, le probl�me, c'est que ce pointeur vers la JVM n'est pas valide dans les fonctions de callback (j'ignore pourquoi) bien que nous l'ayons au pr�alable copi� dans une variable globale depuis une fonction normale. Nous n'avons pas ce probl�me avec un type entier par exemple, ce probl�me ne survient qu'avec les pointeurs � priori...

    Avez vous une id�e du probl�me ? Cela doit sans doute �tre d� � une subtilit� des fonctions de callback ?
    Comment contourner le probl�me ? Nous avons juste besoin de copier ce pointeur depuis une fonction non callback pour y avoir acc�s dans une fonction de callback justement.

    Merci d'avance de votre aide pr�cieuse :-)

  2. #2
    Membre chevronn�
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Par d�faut
    Le probl�me a priori, c'est que le pointeur vers JNIEnv, n'est valide que dans le thread qui l'a requis. Il n'est donc pas possible de passer ce type de pointeur d'un thread vers un autre. Le coup de la variable globale est donc une tr�s mauvaise id�e.

    Lorsque l'on se trouve dans le corps d'une callback, on est dans un thread diff�rent de son thread principal.

    http://www.science.uva.nl/ict/ossdoc...ting/sync.html

  3. #3
    Membre exp�riment�
    Avatar de giminik
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    303
    D�tails du profil
    Informations personnelles :
    �ge : 43
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 303
    Par d�faut
    Merci pour ta r�ponse.
    On m'a conseill� d'utiliser la fonction ReadProcessMemory pour effectuer une copie de JNIEnv mais il semble que cela ne copie pas compl�tement la structure car elle contient �galement des pointeurs... Est-ce que cette solution est viable ?

    The JNI interface pointer (JNIEnv *) is only valid in the current thread. You must not pass the interface pointer from one thread to another, or cache an interface pointer and use it in multiple threads. The Java Virtual Machine will pass you the same interface pointer in consecutive invocations of a native method from the same thread, but different threads pass different interface pointers to native methods.
    Ok, mais alors comment r�cup�rer le pointeur vers JNIEnv depuis un autre thread ?

    Check the use of global variables carefully. Multiple threads might be accessing the global variables at the same time. Make sure that you put in appropriate locks to ensure safety.
    Il n'est vraiment pas possible d'utiliser une variable globale ?

  4. #4
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Apparemment, tu ne peux pas appeler la JNI ainsi depuis un hook.
    Mais tu peux toujours pr�venir un autre thread depuis le hook, un thread qui aurait un pointeur valide sur la JNI...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre chevronn�
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Par d�faut
    Prend ma r�ponse avec des pincettes, je suis un peu rouill� du JNI.
    Citation Envoy� par giminik Voir le message
    On m'a conseill� d'utiliser la fonction ReadProcessMemory pour effectuer une copie de JNIEnv mais il semble que cela ne copie pas compl�tement la structure car elle contient �galement des pointeurs... Est-ce que cette solution est viable ?
    Je ne pense vraiment pas que ce soit une bonne id�e. C'est l'environnement JNI qui est local � un thread, le dupliquer ne ferait que cr�er des probl�mes.

    Ok, mais alors comment r�cup�rer le pointeur vers JNIEnv depuis un autre thread ?
    Je ne suis pas expert, mais j'essaierai les deux choses suivantes:
    - demander un pointeur vers l'environnement dans le thread de la callback (� partir de du pointeur sur la JVM). Je ne me rappelle pas si c'est possible, donc � v�rifier.
    - Traiter toutes les callback dans le thread principal. Cela implique de mettre en place un m�chanisme de communication et de synchronisation entre les callbacks et le thread principal (la callback empile un event, pr�vient le principal, le principal le traite, etc...)

    Intuitivement, je pr�f�re la seconde solution. Elle est plus co�teuse � mettre en place, mais elle a le m�rite d'�tre tr�s claire en terme d'archi.

    Il n'est vraiment pas possible d'utiliser une variable globale ?
    Clairement et d�finitivement non.


    EDIT: Apr�s une petite recherche je suis retomb� sur �a
    http://java.sun.com/docs/books/jni/html/other.html

    Le paragraphe 8.1.4 r�pond au point 1. Je pense que la doc est vieille et que la syntaxe a du changer.

    Cela ne change rien � ma remarque pr�c�dente. Pour moi la vrai solution passe par avoir tout le traitement Java des callback dans un thread unique.

  6. #6
    Membre exp�riment�
    Avatar de giminik
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    303
    D�tails du profil
    Informations personnelles :
    �ge : 43
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 303
    Par d�faut
    La solution 8.1.4 m'aurait bien arrang�, malheureusement je retombe sur le m�me probl�me de pointeur non accessible dans le processus des m�thodes callback.

    Nous avions pens� � utiliser de la m�moire partag�e, il me faudrait alors effectuer une copie de JavaVM, est-ce plus propre que de tenter une copie de JNIEnv ?

    As tu plus d'informations sur la solution num�ro 2 qui n'utilise qu'un seul thread ?
    Avec �ventuellement un petit lien sur un exemple de code ?

  7. #7
    Membre chevronn�
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Par d�faut
    M�moire partag�e, variable globale ou autre �a ne marchera pas.
    L'environnement JNI d�pend du thread. Quelque soit la m�thode de partage, c'est incontournable. Ce que tu proposes reviendrait � recr�er une JVM � chaque appel d'une callback.

    Pour la m�thode 2, c'est assez simple. Sans connaitre plus ton probl�me, j'utiliserai une pattern de type commande.
    Au lieu d'ex�cuter un traitement directement dans le corps de la callback. La callback cr�e une instance de commande et l'empile dans une structure FIFO et notifie le thread qui poss�de la JVM (en allouant un jeton sur un s�maphore par exemple).
    Le thread JVM traite la commande (en appelant la m�thode execute() si on suit la pattern).

    Je n'ai pas de code disponible sous la main, mais c'est assez classique comme impl�mentation. Je peux �ventuellement te filer un coup de pouce, mais je n'ai pas la dispo pour �crire le code enti�rement.

  8. #8
    Membre exp�riment�
    Avatar de giminik
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    303
    D�tails du profil
    Informations personnelles :
    �ge : 43
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 303
    Par d�faut
    La solution que tu proposes m'int�resse.
    Pour la file, pas de probl�me et pour le design pattern commande, je suis d�j� en train de me documenter la dessus.
    Par contre, l� o� je vais gal�rer c'est sur la mani�re de faire la communication entre les threads depuis les m�thodes de callback.
    As tu, � d�faut d'un bout de code, les noms des fonctions qui permettent de faire la communication entre le thread principal et les fonctions de callback, je devrais pouvoir me d�brouiller. Si jamais j'ai des soucis, je reviendrai alors t'emb�ter
    Merci en tout cas de m'�claircir.
    Matthieu

  9. #9
    Membre chevronn�
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Par d�faut
    Citation Envoy� par giminik Voir le message
    As tu, � d�faut d'un bout de code, les noms des fonctions qui permettent de faire la communication entre le thread principal et les fonctions de callback, je devrais pouvoir me d�brouiller. Si jamais j'ai des soucis, je reviendrai alors t'emb�ter
    Ce sont des threads, pas des processus ind�pendants. Il n'y a donc pas de probl�mes � partager des structures de donn�es entre eux, notamment une liste de commandes par exemple.
    Ce qu'il te faut ensuite, c'est un "objet de synchronisation" qui �vite que qu'une callback modifie la liste en m�me temps que le thread JVM. Ceci d�pend de ton OS, mais c'est assez simple. Je te conseille de faire une recherche sur le mod�le "Producteur/Consommateur" avec s�maphore. Tu auras s�rement le bon bout de code pour �a.

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Ao�t 2006
    Messages
    15
    D�tails du profil
    Informations personnelles :
    �ge : 41
    Localisation : Tunisie

    Informations forums :
    Inscription : Ao�t 2006
    Messages : 15
    Par d�faut
    Citation Envoy� par giminik Voir le message
    La solution 8.1.4 m'aurait bien arrang�, malheureusement je retombe sur le m�me probl�me de pointeur non accessible dans le processus des m�thodes callback.

    Nous avions pens� � utiliser de la m�moire partag�e, il me faudrait alors effectuer une copie de JavaVM, est-ce plus propre que de tenter une copie de JNIEnv ?

    As tu plus d'informations sur la solution num�ro 2 qui n'utilise qu'un seul thread ?
    Avec �ventuellement un petit lien sur un exemple de code ?
    pour recuperer JNIEnv je pense qu'il faut attacher le thread a la JVM !

    j'ai utilis� une fois ce code ... peut etre it help !
    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
     
    JNIEnv	*env;
    jvmtiEnv	*jvmti;
    jint	rc;
    jvmtiError	 err;	
     
    if(javaVM->AttachCurrentThread((void **)&env, NULL) >= 0){printf("Thread attaché !\n");}
    else
    	printf("Error: Error on the attach current thread thing!\n");
     
    rc = javaVM->GetEnv((void **)&jvmti, JVMTI_VERSION_1);
    	if (rc  != JNI_OK) {
    		printf("ERROR: Unable to create jvmtiEnv, rc=%d\n", rc);
    		return -1;
    		}
    Merci !

  11. #11
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Une minute...
    Depuis quand les hooks s'ex�cutent-ils hors du thread principal mais forc�ment dans le m�me process ?

    S'il s'agit de hooks qui s'ex�cutent hors du thread principal, alors ils s'ex�cutent dans le thread qui a lanc� l'�v�nement, c'est-�-dire potentiellement un thread d'un autre processus...
    � ce moment-l�, des IPCs seront n�cessaires...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  12. #12
    Membre chevronn�
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Par d�faut
    bonne remarque, j'y connais rien en hook.
    Mais si l'OP pouvait passer une variable globale commune, y'a des chances qu'il soit dans le m�me processus non?

  13. #13
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Le probl�me, c'est que la variable globale en question n'�tait pas vraiment pass�e.
    �a expliquerait que le pointeur soit carr�ment invalide au lieu d'avoir simplement des cons�quences bizarres...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Membre chevronn�
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Par d�faut
    laissons le r�pondre
    Si �a devient trop technique giminik, je suis dispo en MP

  15. #15
    Membre exp�riment�
    Avatar de giminik
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    303
    D�tails du profil
    Informations personnelles :
    �ge : 43
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 303
    Par d�faut
    Citation Envoy� par M�dinoc Voir le message
    S'il s'agit de hooks qui s'ex�cutent hors du thread principal, alors ils s'ex�cutent dans le thread qui a lanc� l'�v�nement, c'est-�-dire potentiellement un thread d'un autre processus...
    Comment puis-je le v�rifier ?
    Il s'agit en fait d'une classe Java qui lance le code natif (qui est donc une dll). Dans cette dll il y a des hook pour �couter une fen�tre windows en particulier : savoir si cette fen�tre est redimensionn�e ou repainte notamment.

    Je tiens � pr�ciser qu'avec une m�moire partag�e, nous arrivons � transmettre des valeurs de type entier dans une variable.

    J'ai une petite question subsidiaire : savez-vous pourquoi lorsqu'on fait des printf ou cout dans les fonctions de callback, rien ne s'affiche dans la console ? Je suis oblig� d'utiliser des Beep() pour faire du deboggage...

  16. #16
    Membre chevronn�
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Par d�faut
    Si tu disposes d'une m�moire partag�e, tu disposes donc d'un canal pour partager une liste de commande. Il te faudra un objet de synchro, et cela existe de base sous windows, que tu aies affaire avec des thread ou des processus.

    Pour le coup de ton printf c'est li�. La console est li�e � ton programme principal. Si la callback est appel�e dans un autre processus, elle n'a aucun acc�s � la console. Par contre, le haut-parleur est commun
    Ce qui explique que le beep fonctionne. Un syst�me de fichier de log serait n�anmoins beaucoup plus propre (et utile sur le long terme).

  17. #17
    Membre exp�riment�
    Avatar de giminik
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    303
    D�tails du profil
    Informations personnelles :
    �ge : 43
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 303
    Par d�faut
    Ok, donc pour r�sumer, je dois utiliser la m�moire partag�e pour stocker tout ce que je souhaite, sauf des pointeurs, c'est bien �a ?
    Je vais donc stocker dans cette m�moire partag�e, une file, et lui envoyer des commandes via le pattern du m�me nom.
    Pour �viter les probl�mes d'acc�s concurrents, je mets un mutex ou �quivalent.
    Et dans un thread s�par�, j'aurai un while (true) qui ira v�rifier si des commandes sont disponibles dans la file (toujours avec le mutex pour �viter les probl�mes d'acc�s concurrents). J'ai peur que ce while (true) consomme trop de ressources CPU...
    J'ai juste ?

  18. #18
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Ce que tu fais, c'est vraiment un hook ou c'est du subclassing ?

    Je pose la question, car j'ai vu la m�me confusion en .Net un peu plus t�t...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  19. #19
    Membre exp�riment�
    Avatar de giminik
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    303
    D�tails du profil
    Informations personnelles :
    �ge : 43
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 303
    Par d�faut
    Euh, je ne connais pas la diff�rence entre les deux.
    Je ne suis pas � l'origine du code mais on m'a dit qu'il s'agissait de hook.
    Si �a peut aider, nous utilisons la fonction suivante pour sa mise en place :
    SetWindowsHookEx()

  20. #20
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    C'est donc bien un hook.
    Le subclassing, c'est jou� avec SetWindowLong() pour remplacer la proc�dure de fen�tre.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Pointeur de M�thode et RTTI
    Par ShaiLeTroll dans le forum Delphi
    R�ponses: 6
    Dernier message: 16/01/2007, 16h04
  2. TIdFTP, pointeur de m�thode et proc�dure normale
    Par marcpleysier dans le forum Delphi
    R�ponses: 4
    Dernier message: 05/01/2007, 10h30
  3. [API Win32 C++ sans MFC] Une m�thode CALLBACK ?
    Par kidpaddle2 dans le forum Windows
    R�ponses: 6
    Dernier message: 17/09/2006, 15h42
  4. [C++] Tableau de pointeurs de m�thode ?
    Par Castagnems dans le forum C++
    R�ponses: 13
    Dernier message: 15/05/2006, 16h45
  5. Pointeur de m�thode
    Par John Fullspeed dans le forum Langage
    R�ponses: 3
    Dernier message: 24/09/2004, 16h04

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