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 :

g_timeout_add() plantage syntaxe?


Sujet :

GTK+ avec C & C++

  1. #1
    Membre confirmé
    Homme Profil pro
    chercheur
    Inscrit en
    Décembre 2012
    Messages
    195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : chercheur

    Informations forums :
    Inscription : Décembre 2012
    Messages : 195
    Par défaut g_timeout_add() plantage syntaxe?
    Bonjour,

    J'ai beau chercher et rechercher encore sur ce forum (et ailleurs d'ailleurs), je n'arrive pas à utiliser la fonction g_timeout_add() dans mon code.

    C'est juste un essai d'affichage en dynamique, avec rafraichissement toutes les secondes (je sais qu'il existe g_timeout_add_seconds(), mais j'aurai de toute facon besoin prochainement de descendre en dessous de la seconde).

    Voici mon code, rapidement:

    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
    /* Exemple simple de mise à jour en dynamique d'un label /*
     
    #include <stdlib.h>
    #include <gtk/gtk.h>
    int i=0,flag_depart=0;
    int main(int argc, char **argv)
    {
        /* déclaration des widgets */
        GtkWidget *pWindow; /*fenetre principale */
        GtkWidget *pLabel; /* un label */
        GtkWidget *pTitre; /* un autre label */
        GtkWidget *pVBox; /* la box verticale */
        GtkWidget *pHBox; /* la box horizontale */
        GtkWidget *pButtonReset; /*  bouton reset */
        GtkWidget *pButtonStart; /*  bouton start */
        GtkWidget *pButtonStop; /*  bouton start */
        gchar* sUtf8;  /* pour formater des chaines de characteres */
        guint period;
     
        void OnDestroy(GtkWidget *pWidget, gpointer pData); /* fonction call back destroy */
        gboolean OnExpose(gpointer pData); /* fonction call back affichage */
        void Press_Start(GtkButton *button, gpointer user_data); /* fonction call back si start */
        void Press_Reset(GtkButton *button, gpointer user_data); /* fonction call back si reset */
        void Press_Stop(GtkButton *button, gpointer user_data); /* fonction call back si stop */
     
        /* Initialisation de GTK+ */
        gtk_init(&argc, &argv);
        /* création de la fenetre */
        pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
         /* définition des paramètres de la fenetre */
        gtk_window_set_position(GTK_WINDOW(pWindow), GTK_WIN_POS_CENTER);
        gtk_window_set_default_size(GTK_WINDOW(pWindow), 500, 500);
        gtk_window_set_title(GTK_WINDOW(pWindow), "Test affichage en dynamique");
        /* création de la box verticale */
        pVBox = gtk_vbox_new(FALSE, 0);
        /* création de la box horizontale */
        pHBox = gtk_hbox_new(TRUE, 0);
        /* création du label */
        pLabel=gtk_label_new(NULL);
        sUtf8 = g_locale_to_utf8("<span font_desc=\"25\"><b>0</b></span>", -1, NULL, NULL, NULL);
        gtk_label_set_markup(GTK_LABEL(pLabel), sUtf8);
        g_free(sUtf8);
        /* création du titre */
        pTitre=gtk_label_new(NULL);
        sUtf8 = g_locale_to_utf8("<span font_desc=\"15\" background=\"#000000\" foreground=\"#FFFFFF\"><b>Test affichage en dynamique</b></span>", -1, NULL, NULL, NULL);
        gtk_label_set_markup(GTK_LABEL(pTitre), sUtf8);
        g_free(sUtf8);
        /* création du bouton reset */
        pButtonReset = gtk_button_new_with_label("Reset");
        /* création du bouton start */
        pButtonStart = gtk_button_new_with_label("Start");
        /* création du bouton stop */
        pButtonStop = gtk_button_new_with_label("Stop");
        /* AJout du titre dans la GtkHBox */
        gtk_box_pack_start(GTK_BOX(pVBox), pTitre, FALSE, TRUE, 10);
        /* Ajout des boutons reset et start dans la GtkHBox */
        gtk_box_pack_start(GTK_BOX(pHBox), pButtonStart, FALSE, TRUE, 0);
        gtk_box_pack_start(GTK_BOX(pHBox), pButtonStop, FALSE, TRUE, 0);
        gtk_box_pack_start(GTK_BOX(pHBox), pButtonReset, FALSE, TRUE, 0);
        /* ajout de la boite horizontale dans la boite verticale */
        gtk_box_pack_start(GTK_BOX(pVBox), pHBox, FALSE, TRUE, 0);
        /* ajout du label dans la GtkVBox */
        gtk_box_pack_start(GTK_BOX(pVBox), pLabel, TRUE, TRUE, 0);
        /* ajout de la GtkVBox à la fenetre */
          gtk_container_add(GTK_CONTAINER(pWindow), pVBox);
        /* Connexion des signaux */
        g_signal_connect(G_OBJECT(pWindow), "destroy", G_CALLBACK(OnDestroy), NULL);
        g_signal_connect(G_OBJECT(pButtonStart),"pressed", G_CALLBACK(Press_Start), NULL);
        g_signal_connect(G_OBJECT(pButtonStop),"pressed", G_CALLBACK(Press_Stop), NULL);
        g_signal_connect(G_OBJECT(pButtonReset),"pressed", G_CALLBACK(Press_Reset), GTK_LABEL(pLabel));
     
        /* fonction g_timeout_add () ici */
        period=(guint)1000;
        g_timeout_add (period, OnExpose, GTK_LABEL(pLabel));
     
        /*affichage de la fenetre */
        gtk_widget_show_all(pWindow);
        /* Demarrage de la boucle evenementielle */
        gtk_main();
        return EXIT_SUCCESS;
    }
    void OnDestroy(GtkWidget *pWidget, gpointer pData){
        /* Arret de la boucle evenementielle */
         gtk_main_quit();
    }
    gboolean OnExpose(gpointer pData){
        /* Mise a jour du label */
        char tempo[1000];
        gchar* sUtf8;
        if (flag_depart)
        {
            (void)sprintf(tempo, "<span font_desc=\"25\"><b>%d</b></span>", i);
            sUtf8 = g_locale_to_utf8(tempo, -1, NULL, NULL, NULL);
            gtk_label_set_markup(GTK_LABEL(pData), tempo);
            i++;
        }
        g_free(sUtf8);
        return TRUE;
    }
    void Press_Reset(GtkButton *button, gpointer user_data) {
        /* reset compteur */
        i=0;
        char tempo[1000];
        gchar* sUtf8;
        (void)sprintf(tempo, "<span font_desc=\"25\"><b>%d</b></span>", 0);
        sUtf8 = g_locale_to_utf8(tempo, -1, NULL, NULL, NULL);
        gtk_label_set_markup(GTK_LABEL(user_data), tempo);
        g_free(sUtf8);
    }
    void Press_Start(GtkButton *button, gpointer user_data) {
        /* start compteur */
        flag_depart=1;
    }
    void Press_Stop(GtkButton *button, gpointer user_data) {
        /* stop compteur */
        flag_depart=0;
    }
    Tout se passe aux lignes 72-74.

    Le code compile bien, la fenetre principale s'affiche. Mais au bout du premier timeout, le code plante.

    J'imagine qu'il y a donc quelque chose que je n'ai pas compris, j'imagine dans la déclaration de la fonction à appeler à intervals réguliers. Tout aide sur ce point est la bienvenue.

    D'avance merci, Eric.

  2. #2
    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
    Bonjour,

    tu aurais trouvé immédiatement la cause du crash en utilisant un débogueur. Le programme crashe ligne 97:
    En regardant un peu plus haut, on se rend compte que tu n'initialises ta variable que dans ton bloc if.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        gchar* sUtf8;
        if (flag_depart)
        {
            /* ... */
             sUtf8 = g_locale_to_utf8(tempo, -1, NULL, NULL, NULL);
            /* ... */
        }
        g_free(sUtf8);
    g_free ne fait rien s'il est appelé sur un pointeur nul, mais là sur un pointeur non initialisé, forcément ça crashe.

    Solution:
    Au passage, évite d'appeler ta callback OnExpose, qui est plutôt un nom de callback qu'on utilise pour le signal "expose-event".

    Autre remarque: globalement, l'approche n'est pas correcte, comme je te l'indiquais en avril dernier. Ton chronomètre va dériver avec le temps si tu n'utilises pas un GTimer.

  3. #3
    Membre confirmé
    Homme Profil pro
    chercheur
    Inscrit en
    Décembre 2012
    Messages
    195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : chercheur

    Informations forums :
    Inscription : Décembre 2012
    Messages : 195
    Par défaut
    Citation Envoyé par liberforce Voir le message
    Bonjour,

    tu aurais trouvé immédiatement la cause du crash en utilisant un débogueur. Le programme crashe ligne 97:
    Merci, mais non. J'ai bien essayé évidement avant de poser la question sur ce forum. J'utilise GDB avec Code::Block. Et j'obtiens:

    Segmentation fault.
    In ntdll!**LdrWx86FormatVirtualImage () (C:\Windows\system32\ntdll.**dll)

    dès que the gtk_main() est lancé.

    Impossible de savoir d'où provenait le bug. D'ailleurs, à cet égard, je suis preneur d'un moyen de débugger plus efficacement, donc, dans cet environement.

    En regardant un peu plus haut, on se rend compte que tu n'initialises ta variable que dans ton bloc if.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        gchar* sUtf8;
        if (flag_depart)
        {
            /* ... */
             sUtf8 = g_locale_to_utf8(tempo, -1, NULL, NULL, NULL);
            /* ... */
        }
        g_free(sUtf8);
    g_free ne fait rien s'il est appelé sur un pointeur nul, mais là sur un pointeur non initialisé, forcément ça crashe.

    Solution:
    Excellent!! Ca marche correctement à présent. Mille mercis!

    Au passage, évite d'appeler ta callback OnExpose, qui est plutôt un nom de callback qu'on utilise pour le signal "expose-event".
    Ok.
    Autre remarque: globalement, l'approche n'est pas correcte, comme je te l'indiquais en avril dernier. Ton chronomètre va dériver avec le temps si tu n'utilises pas un GTimer.
    Oui, oui, je sais. Je fais ca correctement dans mes codes, avec des GTimer et g_timer_elapsed(), etc. Le code ici n'était qu'un essai pour comprendre comment fonctionne g_timout_add().

    Encore merci, en tout cas.

    Eric.

  4. #4
    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
    Pour ton soucis, tu es sûr d'avoir compilé en mode debug ? Parce que là on dirait que tu n'as pas les symboles de debug. L'idéal c'est de compiler avec les options d'optimisation désactivées ("-O0") et les infos de debug max ("-ggdb3").

  5. #5
    Membre confirmé
    Homme Profil pro
    chercheur
    Inscrit en
    Décembre 2012
    Messages
    195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : chercheur

    Informations forums :
    Inscription : Décembre 2012
    Messages : 195
    Par défaut
    Oui, je compile évidement avec les options de debuggage, notamment -g mais aussi sans l'option de strip -s.

    Si le code ne plante pas, je peux mettre des break points, etc. En revanche, si ca plante, je ne peux voir d'où vient le plantage.

    Eric.

  6. #6
    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
    Hum, bizarre. Tu essayé de builder en invoquant gcc en ligne de commande directement ? Tu peux aussi essayer de poster dans un forum spécialisé sur Code::Blocks ou MinGW. Perso j'ai déjà utilisé MinGW sous Windows, je ne me souviens pas avoir eu ce genre de problèmes.

  7. #7
    Membre confirmé
    Homme Profil pro
    chercheur
    Inscrit en
    Décembre 2012
    Messages
    195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : chercheur

    Informations forums :
    Inscription : Décembre 2012
    Messages : 195
    Par défaut
    Je debugge depuis des années avec gdb. Je pensais que le problème dont il est question ici était spécifique de GTK, pensant que le degugger ne gérait pas bien le suivi de ce qui se passe dans la boucle évennementielle de GTK.

    Bah, je vais tâcher de continuer à coder comme ca.

    Merci en tout cas pour les éclaircissements.

    Eric.

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

Discussions similaires

  1. Syntaxe requete
    Par Chipolata dans le forum Langage SQL
    Réponses: 2
    Dernier message: 28/03/2003, 14h22
  2. [Syntaxe] Action simultanée sur plusieurs élements
    Par FranT dans le forum Composants VCL
    Réponses: 2
    Dernier message: 20/03/2003, 20h20
  3. Syntaxe TASM <-> MASM
    Par LFC dans le forum Assembleur
    Réponses: 3
    Dernier message: 28/02/2003, 15h56
  4. [Kylix] Plantage IDE Kylix3/Mandrake 9.0
    Par OmicroN dans le forum EDI
    Réponses: 3
    Dernier message: 28/01/2003, 23h04
  5. [VB6] [Syntaxe] Fonction renvoyant un tableau d'objets
    Par Troopers dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 18/10/2002, 15h33

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