glutTimerFunc et objet ?

glutTimerFunc et objet ? - C++ - Programmation

Marsh Posté le 28-12-2006 à 16:33:15    

Bonjour a tous
 
Je souhaite utiliser la fonction glutTimerFunc sur une méthode de classe :
 
void Maclasse::dessiner(int a)
{
      blablabla...
}
Void Maclasse::animer()
{    ...
      while ( y < 10 )
      {
          y++;
          glutTimerFunc(60, dessiner,1);
      }
}
Mais j'ai malheureusement une erreur de compilation :
   "error: argument of type 'void(Maclasse::)(int)' does not match 'void (*)()' "
 
Quelqu'un a une idée ?
 
Merci

Reply

Marsh Posté le 28-12-2006 à 16:33:15   

Reply

Marsh Posté le 28-12-2006 à 19:00:53    

PB- a écrit :

Bonjour a tous
 
Je souhaite utiliser la fonction glutTimerFunc sur une méthode de classe :
 

void Maclasse::dessiner(int a)
{
      blablabla...
}
Void Maclasse::animer()
{    ...
      while ( y < 10 )
      {
          y++;
          glutTimerFunc(60, dessiner,1);
      }
}


Mais j'ai malheureusement une erreur de compilation :
   "error: argument of type 'void(Maclasse:: )(int)' does not match 'void (*)()' "
 
Quelqu'un a une idée ?
 
Merci


 
Peut-être lui-passer "Maclasse:: dessiner" ou bien "this->dessiner" au lieu de "dessiner" tout court...


Message édité par Sve@r le 28-12-2006 à 19:02:57

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 28-12-2006 à 19:51:06    

ca ne change rien :'(
Merci de ta réponse


Message édité par PB- le 28-12-2006 à 19:51:37
Reply

Marsh Posté le 28-12-2006 à 20:07:58    

En regle générale les fonctions a callback prennent un parametre dont la signification est définie par l'utilisateur. Ici il me semble que c'est le dernier parametre de glutTimerFunc qui se retrouve en parametre de Dessiner.
 
Ce qu'il faut retenir c'est qu'un pointeur de fonction membre et un pointeur de fonction, ca n'est pas la meme chose et on ne peut pas remplacer l'un par l'autre. Cas particulier pour une fonction membre statique, qui ne s'execute pas dans le contexte d'un objet (un en mot, elle n'a pas de pointeur this).
 
Essaie comme ca :

Code :
  1. class MaClasse
  2. {
  3.    public:
  4.       static void callback_dessiner(int val)
  5.       {
  6.          MaClasse* pThis = (MaClasse*)val;
  7.          pThis->dessiner();
  8.       }
  9.    private:
  10.       dessiner();
  11. }
  12. void Maclasse::dessiner()
  13. {
  14.       blablabla...
  15. }
  16. Void Maclasse::animer()
  17. {    ...
  18.       while ( y < 10 )
  19.       {
  20.           y++;
  21.           glutTimerFunc(60, callback_dessiner, this);
  22.       }
  23. }


Message édité par Ace17 le 28-12-2006 à 20:11:34
Reply

Marsh Posté le 28-12-2006 à 20:21:52    

Merci !!! ca marche !!
 
Tu peux m'expliquer cette ligne par contre stp:
 
"MaClasse* pThis = (MaClasse*)val;"
 
(PS:comment tu fais pour mettre des lignes de code avec les numéros dans ton message ? )

Reply

Marsh Posté le 28-12-2006 à 20:45:07    

Lorsqu'on veut appeler la fonction "dessiner", il faut savoir de quel objet cette fonction est membre (imagine que tu aies deux objets de type MaClasse).
Sauf que glut lui ne sait qu'appeler des fonctions et n'a rien a faire de nos histoires d'objet, par contre, il nous propose de lui donner une valeur qu'il passera en parametre a la fonction qu'il appelera.  
Donc nous, dans cette valeur, on met le pointeur vers l'objet, récupéré grace a "this".
Donc lorsqu'on est dans la fonction callback_dessiner, le pointeur vers notre objet est caché dans "val".  
La ligne dont tu demandes la signification sert juste a convertir brutalement val en pointeur vers MaClasse.
Si c'est pas clair, n'hésite pas a redemander.
 
Et pour les lignes numérotées ... il suffit de mettre ton code entre balises "[code]". Edite mon message et tu verras.
 
 
 

Reply

Marsh Posté le 28-12-2006 à 20:48:59    

Merci de ton explication.
 
En fait j'ai une erreur : error: invalid conversion from 'Maclasse* const' to 'int'
                               error: initializing argument 3 of 'void glutTimerFunc(unsigned int, void(*)(int), int )'
 
Je pensais l'avoir corrigé mais après avoir vu ton explication, ce que j'avais fait c'était faut :/
 
Merci de ton aide


Message édité par PB- le 28-12-2006 à 20:55:33
Reply

Marsh Posté le 28-12-2006 à 21:37:41    

Ace17 a écrit :

Lorsqu'on veut appeler la fonction "dessiner", il faut savoir de quel objet cette fonction est membre (imagine que tu aies deux objets de type MaClasse).
Sauf que glut lui ne sait qu'appeler des fonctions et n'a rien a faire de nos histoires d'objet, par contre, il nous propose de lui donner une valeur qu'il passera en parametre a la fonction qu'il appelera.

 
Excellent !!! C'était ce que j'entrevoyais vaguement (j'en connais très peu en C++) quand je disais d'essayer de mettre "Maclasse:: Dessiner".
 

Ace17 a écrit :

Donc nous, dans cette valeur, on met le pointeur vers l'objet, récupéré grace a "this".
Donc lorsqu'on est dans la fonction callback_dessiner, le pointeur vers notre objet est caché dans "val".


Là, je suppute un problème. Apparemment il faut (faudrait) passer à "glut" la valeur "1" qu'il passera à "dessiner". Or toi tu lui passes un pointeur mais tu perds cette fameuse valeur "1"...
 
On pourrait essayer un truc de ce style (un peu sale car je vient du C mais je suis sûr que tu comprendras mon idée)

Code :
  1. class MaClasse;
  2. typedef struct {
  3.     int val;
  4.     MaClasse *ptClasse;
  5. } t_truc;
  6. class MaClasse
  7. {
  8.    public:
  9.       static void callback_dessiner(int ptr)
  10.       {
  11.          t_truc *ptTruc=(t_truc*)ptr;
  12.          ptTruc->ptClasse->dessiner(ptTruc->val);
  13.       }
  14.    private:
  15.       dessiner(int);
  16. }
  17. void Maclasse::dessiner(int val)
  18. {
  19.       blablabla...val...blablabla
  20. }
  21. Void Maclasse::animer()
  22. {    ...
  23.       t_truc truc;
  24.       truc.val=1;
  25.       truc.ptClasse=this;
  26.       while ( y < 10 )
  27.       {
  28.           y++;
  29.           glutTimerFunc(60, callback_dessiner, &truc);
  30.       }
  31. }


Message cité 2 fois
Message édité par Sve@r le 28-12-2006 à 21:44:42

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 28-12-2006 à 21:40:17    

Sve@r a écrit :

Là, je suppute un problème. Apparemment il faut (faudrait) passer à "glut" la valeur "1" qu'il passera à "dessiner". Or toi tu lui passes un pointeur mais tu perds cette fameuse valeur "1"...


 
C'est la correction que j'avais faite, mais ca ne colle pas avec ses explications :(

Reply

Marsh Posté le 28-12-2006 à 21:45:45    

PB- a écrit :

C'est la correction que j'avais faite, mais ca ne colle pas avec ses explications :(


 
J'ai modifié mon post précédent. Maintenant je passe à la fonction "callback" un pointeur vers une structure contenant
- le pointeur vers this qui servira à appeler "dessiner()"
- la valeur utile qu'il passera à "dessiner()"
Cela se pourrait que ça fonctionne...


Message édité par Sve@r le 28-12-2006 à 21:49:33

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 28-12-2006 à 21:45:45   

Reply

Marsh Posté le 28-12-2006 à 21:54:07    

j'essaie et je te dis

Reply

Marsh Posté le 28-12-2006 à 21:59:42    

Meme probleme que ton premier post, erreur de conversion

Reply

Marsh Posté le 28-12-2006 à 22:02:58    

Sve@r a écrit :


Code :
  1. class MaClasse;
  2. typedef struct {
  3.     int val;
  4.     MaClasse *ptClasse;
  5. } t_truc;
  6. class MaClasse
  7. {
  8.    public:
  9.       static void callback_dessiner(int ptr)
  10.       {
  11.          t_truc *ptTruc=(t_truc*)ptr;
  12.          ptTruc->ptClasse->dessiner(ptTruc->val);
  13.       }
  14.    private:
  15.       dessiner(int);
  16. }
  17. void Maclasse::dessiner(int val)
  18. {
  19.       blablabla...val...blablabla
  20. }
  21. Void Maclasse::animer()
  22. {    ...
  23.       t_truc truc;
  24.       truc.val=1;
  25.       truc.ptClasse=this;
  26.       while ( y < 10 )
  27.       {
  28.           y++;
  29.           glutTimerFunc(60, callback_dessiner, &truc);
  30.       }
  31. }




 
Heuuuuuuuuu sauf erreur de ma part, avec cette implémentation, au moment ou le callback va etre appelé la variable locale "truc" aura disparu depuis un certain temps... et le pointeur passé en parametre sera devenu invalide. Pourquoi ne pas mettre ce parametre en dur dans callback_dessiner? Ou dans un membre de MaClasse?

Reply

Marsh Posté le 28-12-2006 à 22:03:48    

Si ce n'est que ca ...

Code :
  1. glutTimerFunc(60, callback_dessiner, (int)this);

Reply

Marsh Posté le 28-12-2006 à 22:12:48    

ok merci erreur  de compile corrigée
 
La fonction glutTimerFunc(60, callback_dessiner, (int)this);  permet bien d'appeler callback_dessiner apres 60 millisecondes, c'est ca ?

Reply

Marsh Posté le 28-12-2006 à 22:15:00    

RTFM

Reply

Marsh Posté le 28-12-2006 à 22:19:56    

lol oki merci de ton aide pour l'application ^^

Reply

Marsh Posté le 29-12-2006 à 10:09:45    

Ace17 a écrit :

Heuuuuuuuuu sauf erreur de ma part, avec cette implémentation, au moment ou le callback va etre appelé la variable locale "truc" aura disparu depuis un certain temps... et le pointeur passé en parametre sera devenu invalide.


Exact - J'aurais dû y penser moi-même car c'est aussi vrai en C. Mais je pense que t'auras compris mon idée d'utiliser une structure pour y mettre à la fois
- le pointeur de l'objet traité
- la valeur à passer à "dessiner()"
Mais effectivement, en y réfléchissant à la lumière du jour, je me rends compte que c'est horrible (ne serait-ce que parce qu'il y a un décalage temporel entre le moment de l'appel à "glut" et le moment de l'appel à "dessiner()" et durant ce décalage, tout peut arriver à "truc" (même s'il est mis en "static" )...
 

Ace17 a écrit :

Si ce n'est que ca ...

Code :
  1. glutTimerFunc(60, callback_dessiner, (int)this);



Euh... et où est passée la valeur "1" qu'on voulait mettre au départ en 3° paramètre de "glutTimerFunc" et qui, si j'ai bien compris, devait être ensuite utilisée comme paramètre de "dessiner()" ???
 

Ace17 a écrit :

Pourquoi ne pas mettre ce parametre en dur dans callback_dessiner? Ou dans un membre de MaClasse?


Ben si la méthode "dessiner()" reçoit un paramètre, c'est visiblement (ou probablement) parce que la valeur en question n'est pas fixe par rapport à l'instance d'objet sinon effectivement elle pourrait très bien être stockée dans un membre de l'objet.


Message édité par Sve@r le 29-12-2006 à 10:26:48

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed