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

GTK+ avec C & C++ Discussion :

Prototype de fonction CALLBACK


Sujet :

GTK+ avec C & C++

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 2
    Par défaut Prototype de fonction CALLBACK
    Ami du jour bonjour.

    Ma question porte sur les prototypes des fonctions que l'on utilise en CALLBACK sur les fonctions g_signal_connect.

    Mon problème : je vois souvent
    ma_fonctioin_callback(GtkWidget* wtf, gpointer* data);
    Pourquoi 2 arguments? C'est quoi ce gtkwidget? (d'où le wtf)
    Je veux dire le gpointer* (apparemment équivalent à un void*) est suffisant, comment la fonction récupère bien le pointeur sur son 2ème argument? Je veux dire logiquement s'il y a un seul argument envoyé il devrait être récupéré en 1er argument...

    Aussi il me semble semble qu'un simple :
    ma_fonctioin_callback( gpointer* data);
    marche...

    Bref, avis aux connaisseur, il me semble que les callback devraient avoir une page dédiée dans les tuto mais il n'en est rien.


    PS : j'ai cherché dans plusieurs cours, en anglais, en français, sur les forums et je n'ai pas trouvé. Je suis à peu près sûr que cette question a déjà été posé mais à dû se perdre dans les méandres du forum.

    PPS : si vous pouvez me faire une petite piqure de rappel contre l'utilisation des variables globales car j'ai toujours un amour fou pour elles mais on me dit souvent que cela pose des problèmes et je me souviens jamais pourquoi...

  2. #2
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    On va essayer de faire simple .

    Tous les prototypes des signaux permettent de récupérer le pointeur du widget qui a émit le signal. Ca a un intérêt.
    Imagine que tu disposes d'un bouton avec un image dedans. Lorsque tu cliques dessus tu veux que l'image dans ce bouton change. Le CallBack associé au signal "clicked" va te permettre de récupérer le pointeur sur le bouton. A partir de là tu applique la modification de l'image.

    Le deuxième pointeur, ou plutôt je dirais le DERNIER pointeur du prototype est un pointeur générique, de type void* comme tu l'as fait remarquer.
    Il te permet de transmettre n'importe qu'elle donnée personnelle au CallBack. En règle général on lui transmet un pointeur sur une structure, mais ca, c'est chacun qui voit...

    Pourquoi j'emploie le mot DERNIER?
    Tout simplement parce qu'il existe un certain nombre de prototypes. Ils n'ont donc pas tous le même nombre d'arguments. Et c'est là que le novice en Gtk+ à tendance à se casser les dents .
    Il est donc IMPERATIF de bien respecter le prototype d'un CallBack associé à un signal donné d'un widget donné pour être sûr de récupérer les informations voulus.

    P.S. : si tu comprends ce que je viens d'écrire tu vois par toi-même qu'on peux se passer des variables globales...

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 2
    Par défaut
    Merci, c'est parfait!

    En effet je viens de tester et on récupère la "fenêtre" (ou autre) parente ce qui est très pratique.

    J'avais bien compris qu'il ne faut pas plus que 2 paramètres mais ça fait toujours du bien de l'entendre.

    Bon je suis pas fan de forcément récupérer le pointeur de l'appelant mais j'imagine que cela simplifie les choses.

  4. #4
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par Kajika Voir le message
    ... Bon je suis pas fan de forcément récupérer le pointeur de l'appelant mais j'imagine que cela simplifie les choses.
    Il est toujours plus façile de se passer d'une chose que l'on a plutôt que d'en avoir besoin et de ne pas la posséder .

  5. #5
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Par défaut
    Citation Envoyé par Kajika Voir le message
    J'avais bien compris qu'il ne faut pas plus que 2 paramètres mais ça fait toujours du bien de l'entendre.

    Bon je suis pas fan de forcément récupérer le pointeur de l'appelant mais j'imagine que cela simplifie les choses.
    Je vais tenter de reformuler:
    Le premier argument d'une callback correspond à l'objet sur lequel est survenu le signal (si tu as utilisé g_signal_connect) ou du moins, celui sur lequel il faut intervenir (si tu as utilise g_signal_connect_swapped). Cela te donne un contexte sur lequel effectuer ton traitement.

    C'est la même chose dans d'autres langages objet: le C++ utilise this (implicite), le python utilise self (explicite). Le C n'étant pas orienté objet, si tu veux utiliser ce paradigme, il te faut forcément indiquer sur quel objet effectuer ton action.

    Les paramètres suivants sont en rapport avec l'action à effectuer. Ils te donnent des informations supplémentaires. Par exemple en réponse à un signal "expose-event" (GTK2) ou "draw" (GTK3), on t'indique quelle zone de l'écran tu dois redessiner.

    Enfin, il y a parfois un paramètre supplémentaire qui permet au développeur de passer des informations complémentaires que lui seul connait, et dont il aura besoin pour effectuer son traitement. Ce paramètre est toujours de type gpointer (qui est en fait du void *) pour permettre de passer un pointeur vers n'importe quel type de donnée. Cela te permettra ainsi de passer un pointeur vers une structure contenant des données, à laquelle tu pourras ainsi accéder dans ta callback, sans avoir à passer par une variable globale (qui est souvent le mal) ! Dans les cas plus simple où une seule donnée est utile et qu'une structure est un peu superflue, tu as des macros de conversion, telle que GINT_TO_POINTER, qui va déguiser un entier signé en pointeur, et sa réciproque à appeler dans une callback, GPOINTER_TO_INT.

    Le problème des variables globales, c'est qu'au bout d'un moment, tu ne sais plus qui a lu dedans, ni qui a écrit dedans, ni dans quel ordre. Le seul cas où c'est à justifiable, c'est pour des raisons de performances, souvent dans l'embarqué. Dans quasiment tout les autres cas, c'est grouic, parce que cela complique la lecture du programme, rend difficile la réutilisation du code dans un autre programme (dès que tu dois rendre ton programme plus généraliste tu dois généralement réécrire des tonnes de code), rend plus difficile sa maintenance et son évolution. Ce n'est donc pas à proscrire, il y a des cas où c'est utile, mais à proscrire pour le débutant.

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

Discussions similaires

  1. Fonction callback
    Par saibe dans le forum Linux
    Réponses: 4
    Dernier message: 19/01/2012, 10h41
  2. [debutant] fonction callback
    Par samipate dans le forum Langage
    Réponses: 5
    Dernier message: 09/10/2005, 14h59
  3. problème fonctions callback
    Par youp_db dans le forum GTK+ avec C & C++
    Réponses: 1
    Dernier message: 02/10/2005, 14h47
  4. [Débutant] fonction CALLBACK
    Par tlt dans le forum MFC
    Réponses: 2
    Dernier message: 29/10/2004, 16h55
  5. Fonction callback dans une classe
    Par julian_ross dans le forum MFC
    Réponses: 8
    Dernier message: 02/03/2004, 11h42

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