Bonjour
Je suis nouveau sur ce forum mais je pense avoir posté au bon endroit. Je travaille actuellement sur un projet en C et je rencontre un problème plutôt intrigant (en fait j'en rencontre plusieurs mais je devrais pouvoir me debrouiller avec ça). J'ai parcouru plusieurs tutoriaux et FAQ (dont celles de developpez.com). Je remercie d'ailleurs les auteurs que j'ai lu (Franck Hecht et Nicolas Joseph) cela m'a permis de bien avancer.
Le problème que je rencontre actuellement est le suivant:
j'appelle une fonction en appuyant sur un bouton.
cette fonction prend en parametre le Widget et une structure de Type Params dont voici la définition
Code : Sélectionner tout - Visualiser dans une fenêtre à part g_signal_connect (gtk_builder_get_object (p_builder, "btn_Ajout_Noeud"),"clicked", G_CALLBACK (Ajouter_Noeud),(gpointer) &Mesparametres);
la fonction doit récupérer le contenu de deux champs et initialiser une structure de type Noeud.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 typedef struct Params{ Reseau * Res; int * Entiers; /*Fenetre*/ GtkWidget * MonWidget; /*permet de récuperer tous les composants*/ GtkBuilder *build; /*Nom du fichier*/ char * NomFichier; /*Gestion des couleurs*/ GdkColormap *colormap; GdkGC * ContexteCouleur; GdkColor * couleurs; }Params;
Ensuite la fonction remplit une boite de texte (TGtkTextView) avec les principales informations du Noeud.
Ensuite elle vide le contenu des champs de saisie.
J'ai modifié plusieurs fois la fonction pour contourner les problèmes de SIGABRT qui semblaient sortir de nulle part (car avant je récupérais les contenu des champs en utilisant l'event "changed").
Maintenant la fonction se termine bien mais une fois terminée une exeption de type SIGSEV est levée (erreur de segmentation). J'ai cherché exactement ou se trouvait l'erreur en utilisant le debuggueur (et les breakpoints).
voici les lignes issues d'un debuggage instruction par instruction
Bien entendu je n'appelle pas la foncton g_closure_invoke et g_cclosure_marshal. (je suppose qu'elle sont appelées en fin de fonction de callback.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 At /home/mylee/Dossier TP/Projet/main.c:207 In g_cclosure_marshal_VOID__VOID () (/usr/lib/libgobject-2.0.so.0) In g_cclosure_marshal_VOID__VOID () (/usr/lib/libgobject-2.0.so.0) In g_cclosure_marshal_VOID__VOID () (/usr/lib/libgobject-2.0.so.0) In g_cclosure_marshal_VOID__VOID () (/usr/lib/libgobject-2.0.so.0) In g_cclosure_marshal_VOID__VOID () (/usr/lib/libgobject-2.0.so.0) In g_cclosure_marshal_VOID__VOID () (/usr/lib/libgobject-2.0.so.0) In g_closure_invoke () (/usr/lib/libgobject-2.0.so.0) In g_closure_invoke () (/usr/lib/libgobject-2.0.so.0) In g_closure_invoke () (/usr/lib/libgobject-2.0.so.0) Program received signal SIGSEGV, Segmentation fault. In g_closure_invoke () (/usr/lib/libgobject-2.0.so.0)
j'ai voulu voir le contenu de g_closure_invoke pour voir ce qui aurait pu poser problème mais je n'y ai pas accès (ce qui me semble normal étant donné que les bibliothèques sont construites).
je vous donne le code de la fonction. Mais je ne peux pas vous joindre le code complet (le fichier main.c fait plus de 500 lignes....)
J'ai pensé que un champ de la focntion appelée pouvait etre a NULL mais en regardant le prototype de la fonction g_closure_invoke ça m'a laissé... un peu bête..
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 static void Ajouter_Noeud(GtkWidget * Comp,gpointer gtkPointer) { Params * Mesparams= (Params *)gtkPointer; GtkBuilder * Build; GtkWidget * txtbox; GtkWidget * Coord_X; //premiere boite de saisie GtkWidget * Coord_Y;//deuxieme boite de saisie int x,y; Build= (* Mesparams).build; //je récupère le gtkBuilder (j'utilise glade 3 pour générer l'interface /*On récupère les Objets correspondant aux boites de champ*/ Coord_X=(GtkWidget *)gtk_builder_get_object (Build, "txt_CoordX"); Coord_Y=(GtkWidget *)gtk_builder_get_object (Build, "txt_CoordY"); /*fonctions de conversion standard (pas de atoi.. itoa....)*/ x=(int)strtol(gtk_entry_get_text(GTK_ENTRY(Coord_X)),NULL,10); y=(int)strtol(gtk_entry_get_text(GTK_ENTRY(Coord_Y)),NULL,10); /*Création du Noeud*/ (*((*Mesparams).Res)).Noeuds[(*Mesparams).Entiers[2]]=Creer_Noeud(x,y,(*Mesparams).Entiers[2]); /*Initialisation du paramètre Alpha (*((*Mesparams).Res)).Alpha=(*Mesparams).Entiers[5]; /*On récupère le textview qui va indiquer le contenu des noeuds saisis*/ txtbox=(GtkWidget *)gtk_builder_get_object (Build, "txt_AjoutNoeuds"); GtkTextBuffer * MonBuff=gtk_text_view_get_buffer(GTK_TEXT_VIEW(txtbox)); GtkTextIter debut; GtkTextIter fin; gtk_text_buffer_get_start_iter(MonBuff,&debut); gtk_text_buffer_get_end_iter(MonBuff,&fin); char *num; char *X; char *Y; sprintf(num,"%d",(*Mesparams).Entiers[2]); sprintf(X,"%d",x); sprintf(Y,"%d",y); char *texte; /*Récupération du contenu du textview et concaténation des nouveaux rsultats*/ texte=gtk_text_buffer_get_text(MonBuff,&debut,&fin,FALSE); texte=strcat(texte," Num:"); texte=strcat(texte,num); texte=strcat(texte," X:"); texte=strcat(texte,X); texte=strcat(texte," Y:"); texte=strcat(texte,Y); texte=strcat(texte,"||"); gtk_text_buffer_set_text(MonBuff,texte,strlen(texte)); gtk_text_view_set_buffer(GTK_TEXT_VIEW(txtbox),MonBuff); /*Vidage des champs*/ gtk_entry_set_text(GTK_ENTRY(Coord_X),""); gtk_entry_set_text(GTK_ENTRY(Coord_Y),""); (*Mesparams).Entiers[2]++; //Incrémentation du numéro de Noeud }
Notes:
Je travaille sur une machine virtuelle (virtualbox+ Debian). J'ai aussi fait un apt-get update et upgrade dans l'espoir que ce soit une erreur de version mais ça n'a rien changé.
Je connais (un peu) d'autres langages de programmation (C#, Java, C++ (bases) ) mais le cahier des charges spécifie que cela soit fait en C.
J'ai essayé de rendre mon message lisible et compréhensible mais étant donné que ça fait longtemps que je n'ai pas fréquenté de forums je devrai surement l'éditer pour aérer un peu.
[EDIT] après quelques tests complémentaires, j'ai essayé en commentant la partie qui effectue le remplissage de la textView (ça fait deux jours que je suis sur le problème et je n'avais pas pensé à ça....) ainsi que le vidage des boites de dialogue et ça fonctionne. Je vais essayer de trouver quelles sont les lignes incriminées
Partager