Problème header
RésoluJ'ai toujours eu de problèmes avec les headers, et je m'en suis toujours sorti "à l'arrache", mais là, je n'ai pas vraiment le choix, et ca me pose vraiment problème, ce que je vais vous expliquer de suite:
Je veux qu'une variable de type gchar* soit partagé entre mes fichiers.
J'ai donc dans mon fichier main:
#include "generateur.c"
dans mon fichier generateur.c:
#include "generateur.h"
et dans mon generateur.h (entre autres):
extern gchar* cheminFichierFil;
Mais quand je veux changer la valeur de mon cheminFichierFil dans mon fichier main, le compilateur me dis que cheminFichierFil n'est pas déclaré ...
Je vous supplie donc de m'aider parce que les headers et moi sommes en guerre depuis mes débuts.
Merci d'avance,
Sheeps.
34 réponses
Le problème central est le partage d'une variable de type gchar* entre plusieurs fichiers C via extern, alors que le compilateur signale une non-déclaration lorsque la variable est modifiée depuis main. Des extern dans le header générateur.h et une définition unique de la variable dans un fichier C, avec l'inclusion du header dans chaque fichier source, permet d'éviter les erreurs de liaison et les redéfinitions. La recommandation clé est d'inclure le header approprié dans le fichier principal avant d'utiliser le fichier .c correspondant et de ne pas inclure directement un .c. D'autres éléments de contexte ont été évoqués, comme corriger les définitions dans generateur.c et vérifier que la variable n'est pas redéfinie dans main.cpp.
-
Ouf !
Heureux de t'avoir rendu service.
J'vais aller prendre un café tranquille, maintenant ;) -
YOUHOOOO ! ! !
Ca marche !
Du coup j'ai fais l'isolement et la continuité tout seul grace à tes explications.
Tout ca pour 2 petits points ...
Merci énormément !
T'as fini par l'avoir ^^ -
Ça m'étonnerait que ça le dérange... Dans le doute, peux-tu le déplacer ou le renommer ?
En essayant de reproduire ton cas de figure chez moi, j'ai vu qu'il n'acceptait pas les points dans les define. Peux-tu au début de generateur.h remplacer
#ifndef generateur.h
#define generateur.h
par
#ifndef generateurh
#define generateurh -
Mes 3 fichiers sont dans le même répertoire et je n'ai qu'un .h
j'ai un "generateur.h.gch" par contre c'est pas gênant? -
Chaque chose en son temps, commençons par la compilation
As-tu bien un seul fichier generateur.h ? Tes 3 fichiers sont-ils bien dans le même répertoire ? -
J'ai essayé, mais à tous les coups j'avais oublié de remettre en commentaire le
gchar* cheminFichierFil = NULL;
dans le main.cpp, du coup il le connaissait forcément.
Si tu veux essayer l'autre problème, je le remet, et ca me donne bien les erreurs du L I N K E R sur la continuité et l'isolement. Même avec seulement les extern dans le .h et sans aucune déclaration.
Pourtant crois-moi, il n'y a que extern Isolement isolement; et pareil pour lla continuité dans le .h ...
Ca commence à devenir de l'acharnement la ... ^^ -
J'avoue que je ne comprends pas ... Avant midi, ça, compilait, le problème était à l'édition de liens. Les modifs que je t'ai fait faire à 12h05 n'ont aucun rapport avec cette variable.
Peux-tu revenir à la situation d'avant midi et recréer la même erreur à l'édition de lien, sans erreur de compilation ? -
Non, c'est un problème de compilation pour la première erreur:
C:\Documents and Settings\jfaure\Bureau\stage1\testtest\main.cpp||In function 'int main(int, char**)':| C:\Documents and Settings\jfaure\Bureau\stage1\testtest\main.cpp|110|error: 'cheminFichierFil' was not declared in this scope| ||=== Build finished: 1 errors, 0 warnings ===|
Je l'ai mis au tout début, juste après la ligne #include "generateur.h" (dans generateur.cpp, generateur.c n'existant plus)
J'ai fais un rebuild complet, rien ne change... -
Petit bémol (et tu vas rire): grrr... je l'aurai un jour, je l'aurai... ^^
Je ne sais pas pourquoi l'erreur pour le cheminFichierFil est revenue Effectivement, s'il n'y a pas de définition, c'est normal d'avoir cette erreur. Peux-tu copier le message exact pour vérifier qu'il s'agit bien d'un problème d'édition de lien et non pas de compilation ?
le définir: gchar* cheminFichierFil; dans le generateur.cpp. . Ça devrait être bon... À quelle ligne de ton fichier generateur.c as-tu mis cette ligne ?
As-tu fait un rebuild complet du projet ? -
okok, j'ai capté le truc et j'ai modifié ce qui était à modifier merci beaucoup.
Petit bémol (et tu vas rire):
Je ne sais pas pourquoi l'erreur pour le cheminFichierFil est revenue.
J'ai donc supposé que je pouvais laisser la déclaration: extern gchar* cheminFichierFil; dans le generateur.h et le définir: gchar* cheminFichierFil; dans le generateur.cpp. Mais il ne me le reconnait toujours pas, et je suis obligé de le définir dans le main.cpp.
Une fois défini dans le main (pour vérifier le fonctionnement de l'isolement et de la continuité), j'ai fais ce que tu m'as dis et me retrouve toujours avec une multiple définition...
Désolé d'avoir à t'apprendre ca... ^^ -
Vu le problème...
Dans ton fichier generateur.h, les lignes Isolement isolement; et Continuite continuite; sont de DEFINITIONS de variables (il n'y a pas "extern") et non pas des déclarations.
Quand tu inclus generateur.h dans main.cpp, il crée donc ces variables.
Quand tu inclus generateur.h dans generateur.cpp, il les crée aussi.
Au moment de l'édition de liens, ces variables existent deux fois : c'est ça la double définition
Dans ton fichier .h, il faut mettre
extern Isolement isolement;
extern Continuite continuite;
Ça ce ne sont que des déclarations. Ça ne crée pas de variables, mais ça dit au compilateur qu'elles existent quelque part : tu peux compiler, il les connaît.
Par contre, il faudra bien créer réellement ces variables quelque part (mais une seule fois)
Le plus logique dans ton cas est dans generateur.c :
Isolement isolement;
Continuite continuite;
(pas avant le include generateur.h, sinon il ne connaît pas les types Isolement et Continuite) -
Merci beaucoup !
-
En effet, c'est très différent... Ce n'est plus le compilateur qui se plaint, c'est l'éditeur de liens (L I N K E R). Il y a des choses qui sont définies plusieurs fois (d'où l'importance de ne pas confondre définition et déclaration). Je regarde et je te fais signe
-
et enfin les erreurs:
obj\Debug\generateur.o||In function 'Z19TraitementBoutonGenP10_GtkWidgetPcS1_10Continuite9Isolement':| C:\Documents and Settings\jfaure\Bureau\stage1\testtest\generateur.cpp|8|multiple definition of 'isolement'| obj\Debug\main.o:C:\Documents and Settings\jfaure\Bureau\stage1\testtest\main.cpp|46|first defined here| obj\Debug\generateur.o||In function 'Z19TraitementBoutonGenP10_GtkWidgetPcS1_10Continuite9Isolement':| C:\Documents and Settings\jfaure\Bureau\stage1\testtest\generateur.cpp|9|multiple definition of 'continuite'| obj\Debug\main.o:C:\Documents and Settings\jfaure\Bureau\stage1\testtest\main.cpp|48|first defined here| ||=== Build finished: 4 errors, 0 warnings ===|
-
et main.cpp:
#include "generateur.h" //ATTENTION ! ! ! //chemin du fichier des connections //la je l'ai mis en commentaire pour pouvoir compiler mais je compte le virer //gchar* cheminFichierFil = NULL; //chemin du fichier des définitions de connecteurs gchar* cheminFichierPrf = NULL; //Créé la boîte de dialogue nous permettant de sélectionner un fichier.FIL pour récupérer son chemin void TraitementBoutonFil(GtkWidget* pWidget, gchar* cheminFichierFil); GtkWidget* EntryFil = NULL; //Entry du chemin du fichier des connections //Créé la boîte de dialogue nous permettant de sélectionner un fichier.PRF pour récupérer son chemin void TraitementBoutonPrf(GtkWidget* pWidget, gchar* cheminFichierPrf); GtkWidget* EntryPrf = NULL; //Entry du chemin du fichier des définitions de connecteurs //Créé la boîte de dialogue nous permettant de modifier les paramètres de continuité void TraitementBoutonConti(GtkWidget* pWidget, gpointer data); //entrys des paramètres de continuité GtkWidget* EntryConti1= NULL; GtkWidget* EntryConti2= NULL; GtkWidget* EntryConti3= NULL; GtkWidget* EntryConti4= NULL; GtkWidget* EntryConti5= NULL; //Créé la boîte de dialogue nous permettant de modifier les paramètres d'isolement void TraitementBoutonIso(GtkWidget* pWidget, gpointer data); //entrys des paramètres d'isolement GtkWidget* EntryIso1= NULL; GtkWidget* EntryIso2= NULL; GtkWidget* EntryIso3= NULL; GtkWidget* EntryIso4= NULL; GtkWidget* EntryIso5= NULL; //Ferme le programme void TraitementBoutonClose(GtkWidget* pWidget, GtkWidget* FenetrePrincipale); int main(int argc,char **argv) { //Ouverture de la librairie graphique GTK+ gtk_init(&argc,&argv); //Glossaire des widgets graphiques GtkWidget* FenetrePrincipale = NULL; //Fenêtre principale GtkWidget* frame = NULL; //Frame principale(faisant toute la fenêtre GtkWidget* table = NULL; //Tableau graphique pour placer les éléments GtkWidget* LabelBienvenue = NULL; //Label de présentation gchar* TexteBienvenue = NULL; //Texte associé au label de présentation GtkWidget* boxBienvenue = NULL; //Box contenant l'alignement du label de bienvenue GtkWidget* alignementBienvenue = NULL; //Alignement du label de bienvenue GtkWidget* LabelFil = NULL; //Label de renseignement du fichier de connections gchar* TexteFil = NULL; //Texte associé au label de connections GtkWidget* BoutonFil = NULL; //Bouton pour sélectionner le fichier de connections GtkWidget* boxFil = NULL; //Box pour contenir l'alignement du bouton de connections GtkWidget* alignementFil = NULL; //Alignement du bouton des connections GtkWidget* LabelPrf = NULL; //Label de renseignement de la description des connecteurs gchar* TextePrf = NULL; //Texte associé au label de description GtkWidget* BoutonPrf = NULL; //Bouton pour sélectionner le fichier de description GtkWidget* boxPrf = NULL; //Box pour contenir l'alignement du bouton de description GtkWidget* alignementPrf = NULL; //Alignement du bouton de description GtkWidget* BoutonConti = NULL; //Bouton pour modifier les paramètres de continuité gchar* TexteConti = NULL; //Texte associé au bouton de continuité GtkWidget* boxConti = NULL; //Box pour contenir l'alignement du bouton de continuité GtkWidget* alignementConti = NULL; //Alignement du bouton de continuité GtkWidget* BoutonIso = NULL; //Bouton pour modifier les paramètres d'isolement gchar* TexteIso = NULL; //Texte associé au bouton d'isolement GtkWidget* boxIso = NULL; //Box pour contenir l'alignement du bouton d'isolement GtkWidget* alignementIso = NULL; //Alignement du bouton d'isolement GtkWidget* BoutonGen = NULL; //Bouton pour générer le code winpass gchar* TexteGen = NULL; //Texte associé au bouton de génération GtkWidget* boxGen = NULL; //Box pour contenir l'alignement du bouton de génération GtkWidget* alignementGen = NULL; //Alignement du bouton de génération GtkWidget* BoutonClose = NULL; //Bouton pour fermer le programme GtkWidget* boxClose = NULL; //Box pour contenir l'alignement du bouton de fermeture GtkWidget* alignementClose = NULL; //Alignement du bouton de fermeture //initialisation des paramètres de continuité continuite.Conti1 = "default"; continuite.Conti2 = "default"; continuite.Conti3 = "default"; continuite.Conti4 = "default"; continuite.Conti5 = "default"; //initialisation des paramètres d'isolement isolement.Iso1 = "default"; isolement.Iso2 = "default"; isolement.Iso3 = "default"; isolement.Iso4 = "default"; isolement.Iso5 = "default"; //initialisation du chemin des fichiers gchar* InitChemin =g_locale_to_utf8( "Chemin du fichier...", -1, NULL, NULL, NULL); cheminFichierFil = InitChemin; cheminFichierPrf = InitChemin; //****************************************************************************************** // Création de la fenêtre //****************************************************************************************** FenetrePrincipale = gtk_window_new(GTK_WINDOW_TOPLEVEL); g_signal_connect(G_OBJECT(FenetrePrincipale), "delete-event", G_CALLBACK(gtk_main_quit), NULL); //Titre de la fenêtre gtk_window_set_title(GTK_WINDOW(FenetrePrincipale), "Generateur de code Winapss5000"); //Taille de la fenêtre gtk_window_set_default_size(GTK_WINDOW(FenetrePrincipale), 700, 500); //Positionnement de la fenêtre gtk_window_set_position(GTK_WINDOW(FenetrePrincipale),GTK_WIN_POS_CENTER); //****************************************************************************************** // Création de la hiérarchie graphique de la fenêtre //****************************************************************************************** frame = gtk_frame_new (""); table = gtk_table_new(8, 6, TRUE); gtk_container_add (GTK_CONTAINER (frame), table); //*************************************************** //Label de bienvenue //*************************************************** //Formalisation du texte TexteBienvenue = g_locale_to_utf8( "<span size=\"xx-large\"><b>Générateur Winapass5000</b></span>", -1, NULL, NULL, NULL); //Création du label LabelBienvenue = gtk_label_new(TexteBienvenue); //Libération de la mémoire g_free(TexteBienvenue); //Formalisation grâce aux balises pango gtk_label_set_use_markup(GTK_LABEL(LabelBienvenue), TRUE); //Création de la box pour contenir l'alignement du label boxBienvenue = gtk_vbox_new(TRUE, 1); //Création de l'alignement du label alignementBienvenue = gtk_alignment_new(0.5, 0, 0, 0); //Hiérarchie des composants graphiques pour le label de bienvenue gtk_container_add (GTK_CONTAINER(alignementBienvenue), LabelBienvenue); gtk_container_add (GTK_CONTAINER (boxBienvenue), alignementBienvenue); gtk_table_attach_defaults(GTK_TABLE(table), boxBienvenue, 0, 6, 0, 1 ); //*************************************************** //Label de renseignement du fichier de connections //*************************************************** //Formalisation du texte TexteFil = g_locale_to_utf8( "Veuillez renseigner le fichier de connections (fichier.FIL) :", -1, NULL, NULL, NULL); //Création du label LabelFil = gtk_label_new(TexteFil); //Libération de la mémoire g_free(TexteFil); //Placement du label dans le tableau gtk_table_attach_defaults(GTK_TABLE(table), LabelFil, 0, 4, 1, 2); //*************************************************** //Bouton de renseignement du fichier de connections //*************************************************** //Création du bouton BoutonFil = gtk_button_new_with_mnemonic("Parcourir"); //Création de la box pour contenir l'alignement du bouton boxFil = gtk_vbox_new(TRUE, 1); //Création de l'alignement du bouton alignementFil = gtk_alignment_new(0, 0.5, 0, 0); //Hiérarchie des composants graphiques gtk_container_add (GTK_CONTAINER(alignementFil), BoutonFil); gtk_container_add (GTK_CONTAINER (boxFil), alignementFil); gtk_table_attach_defaults(GTK_TABLE(table), boxFil, 4, 5, 1, 2); //Ecoute du bouton g_signal_connect(G_OBJECT(FenetrePrincipale), "destroy", G_CALLBACK(gtk_main_quit), NULL); g_signal_connect(G_OBJECT(BoutonFil), "clicked", G_CALLBACK(TraitementBoutonFil), NULL); //*************************************************** //Entry du chemin du fichier de connections //*************************************************** //Création de l'entry EntryFil = gtk_entry_new(); //initialisation du texte de l'entry gtk_entry_set_text(GTK_ENTRY(EntryFil), cheminFichierFil); //Placement de l'entry dans le tableau gtk_table_attach_defaults(GTK_TABLE(table), EntryFil, 1, 5, 2, 3); //************************************************************ //Label de renseignement du fichier de définition connecteurs //************************************************************ //Formalisation du texte TextePrf = g_locale_to_utf8("Veuillez renseigner le fichier de définition des connecteurs (fichier.PRO) :", -1, NULL, NULL, NULL); //Création du label LabelPrf = gtk_label_new(TextePrf); //Libération de la mémoire g_free(TextePrf); //Placement du label dans le tableau gtk_table_attach_defaults(GTK_TABLE(table), LabelPrf, 0, 4, 3, 4); //************************************************************* //Bouton de renseignement du fichier de définition connecteurs //************************************************************* //Création du bouton BoutonPrf = gtk_button_new_with_mnemonic("Parcourir"); //Création de la box pour contenir l'alignement du bouton boxPrf = gtk_vbox_new(TRUE, 1); //Création de l'alignement du bouton alignementPrf = gtk_alignment_new(0, 0.5, 0, 0); //Hiérarchie des composants graphiques gtk_container_add (GTK_CONTAINER(alignementPrf), BoutonPrf); gtk_container_add (GTK_CONTAINER (boxPrf), alignementPrf); gtk_table_attach_defaults(GTK_TABLE(table), boxPrf, 4, 5, 3, 4); //Ecoute du bouton g_signal_connect(G_OBJECT(FenetrePrincipale), "destroy", G_CALLBACK(gtk_main_quit), NULL); g_signal_connect(G_OBJECT(BoutonPrf), "clicked", G_CALLBACK(TraitementBoutonPrf), NULL); //************************************************************* //Entry du chemin du fichier de définition connecteurs //************************************************************* //Création de l'entry EntryPrf = gtk_entry_new(); //initialisation du texte de l'entry gtk_entry_set_text(GTK_ENTRY(EntryPrf), cheminFichierPrf); //Placement de l'entry dans le tableau gtk_table_attach_defaults(GTK_TABLE(table), EntryPrf, 1, 5, 4, 5); //************************************************************* //Bouton de paramètre de continuité //************************************************************* //Création du bouton TexteConti = g_locale_to_utf8("Paramètres de continuité",-1, NULL, NULL, NULL); BoutonConti = gtk_button_new_with_label(TexteConti); //Création de la box pour contenir l'alignement du bouton boxConti = gtk_vbox_new(TRUE, 1); //Création de l'alignement du bouton alignementConti = gtk_alignment_new(0, 0.5, 0.5, 0); //Hiérarchie des composants graphiques gtk_container_add (GTK_CONTAINER(alignementConti), BoutonConti); gtk_container_add (GTK_CONTAINER (boxConti), alignementConti); gtk_table_attach_defaults(GTK_TABLE(table), boxConti, 2, 5, 5, 6); //Ecoute du bouton g_signal_connect(G_OBJECT(FenetrePrincipale), "destroy", G_CALLBACK(gtk_main_quit), NULL); g_signal_connect(G_OBJECT(BoutonConti), "clicked", G_CALLBACK(TraitementBoutonConti), NULL); //************************************************************* //Bouton de paramètre d'isolement //************************************************************* //Création du bouton TexteIso = g_locale_to_utf8("Paramètres d'isolement",-1, NULL, NULL, NULL); BoutonIso = gtk_button_new_with_label(TexteIso); //Création de la box pour contenir l'alignement du bouton boxIso = gtk_vbox_new(TRUE, 1); //Création de l'alignement du bouton alignementIso = gtk_alignment_new(0, 0.5, 0.5, 0); //Hiérarchie des composants graphiques gtk_container_add (GTK_CONTAINER(alignementIso), BoutonIso); gtk_container_add (GTK_CONTAINER (boxIso), alignementIso); gtk_table_attach_defaults(GTK_TABLE(table), boxIso, 2, 5, 6, 7); //Ecoute du bouton g_signal_connect(G_OBJECT(FenetrePrincipale), "destroy", G_CALLBACK(gtk_main_quit), NULL); g_signal_connect(G_OBJECT(BoutonIso), "clicked", G_CALLBACK(TraitementBoutonIso), NULL); //************************************************************* //Bouton de génération du code winpass //************************************************************* //Création du bouton TexteGen = g_locale_to_utf8("Générer",-1, NULL, NULL, NULL); BoutonGen = gtk_button_new_with_label(TexteGen); //Création de la box pour contenir l'alignement du bouton boxGen = gtk_vbox_new(TRUE, 1); //Création de l'alignement du bouton alignementGen = gtk_alignment_new(0, 0.5, 0.5, 0); //Hiérarchie des composants graphiques gtk_container_add (GTK_CONTAINER(alignementGen), BoutonGen); gtk_container_add (GTK_CONTAINER (boxGen), alignementGen); gtk_table_attach_defaults(GTK_TABLE(table), boxGen, 4, 5, 7, 8); //Ecoute du bouton g_signal_connect(G_OBJECT(FenetrePrincipale), "destroy", G_CALLBACK(gtk_main_quit), NULL); g_signal_connect(G_OBJECT(BoutonGen), "clicked", G_CALLBACK(TraitementBoutonGen), NULL); //************************************************************* //Bouton de fermeture du programme //************************************************************* //Création du bouton BoutonClose = gtk_button_new_with_label("Fermer"); //Création de la box pour contenir l'alignement du bouton boxClose = gtk_vbox_new(TRUE, 1); //Création de l'alignement du bouton alignementClose = gtk_alignment_new(0, 0.5, 0.5, 0); //Hiérarchie des composants graphiques gtk_container_add (GTK_CONTAINER(alignementClose), BoutonClose); gtk_container_add (GTK_CONTAINER (boxClose), alignementClose); gtk_table_attach_defaults(GTK_TABLE(table), boxClose, 5, 6, 7, 8); //Ecoute du bouton g_signal_connect(G_OBJECT(FenetrePrincipale), "destroy", G_CALLBACK(gtk_main_quit), NULL); g_signal_connect(G_OBJECT(BoutonClose), "clicked", G_CALLBACK(TraitementBoutonClose), FenetrePrincipale); //*************************************************** //Ajout des composants dans la fenêtre et affichage //*************************************************** gtk_container_add(GTK_CONTAINER(FenetrePrincipale),frame); gtk_widget_show_all(FenetrePrincipale); gtk_main(); return EXIT_SUCCESS; } //**************************************************************************** //Traitement du bouton "Parcourir" du fichier de connections //**************************************************************************** void TraitementBoutonFil(GtkWidget* pWidget, gchar* cheminFichierFil) { //Glossaire des widgets graphiques de TraitementBoutonFil GtkWidget* FenetreSelection; GtkWidget* FenetreParent; //Creation de la fenetre de selection FenetreSelection = gtk_file_chooser_dialog_new("Ouvrir...", GTK_WINDOW(FenetreParent), GTK_FILE_CHOOSER_ACTION_OPEN, "Ouvrir", GTK_RESPONSE_OK, "Annuler", GTK_RESPONSE_CANCEL, NULL); //On limite les actions a cette fenetre gtk_window_set_modal(GTK_WINDOW(FenetreSelection), TRUE); //Affichage de la fenetre switch(gtk_dialog_run(GTK_DIALOG(FenetreSelection))) { case GTK_RESPONSE_OK: //Recuperation du chemin cheminFichierFil = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(FenetreSelection)); gtk_entry_set_text(GTK_ENTRY(EntryFil), cheminFichierFil); break; default: //[aucune instruction] break; } gtk_widget_destroy(FenetreSelection); } //**************************************************************************** //Traitement du bouton "Parcourir" du fichier de définition des connecteurs //**************************************************************************** void TraitementBoutonPrf(GtkWidget* pWidget, gchar* cheminFichierPrf) { //Glossaire des widgets graphiques de TraitementBoutonPrf GtkWidget* FenetreSelection; GtkWidget* FenetreParent; //Creation de la fenetre de selection FenetreSelection = gtk_file_chooser_dialog_new("Ouvrir...", GTK_WINDOW(FenetreParent), GTK_FILE_CHOOSER_ACTION_OPEN, "Ouvrir", GTK_RESPONSE_OK, "Annuler", GTK_RESPONSE_CANCEL,NULL); //On limite les actions a cette fenetre gtk_window_set_modal(GTK_WINDOW(FenetreSelection), TRUE); //Affichage de la fenetre switch(gtk_dialog_run(GTK_DIALOG(FenetreSelection))) { case GTK_RESPONSE_OK: //Recuperation du chemin cheminFichierPrf = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(FenetreSelection)); gtk_entry_set_text(GTK_ENTRY(EntryPrf), cheminFichierPrf); break; default: //[aucune instruction] break; } gtk_widget_destroy(FenetreSelection); } //**************************************************************************** //Traitement du bouton des paramètres de continuité //**************************************************************************** void TraitementBoutonConti(GtkWidget* pWidget, gpointer data) { //Glossaire des widgets graphiques de TraitementBoutonConti GtkWidget* FenetreConti; GtkWidget* FenetreParent; //Creation de la fenetre de selection FenetreConti = gtk_dialog_new_with_buttons( "Parametres de continuite", GTK_WINDOW(FenetreParent), GTK_DIALOG_DESTROY_WITH_PARENT, "OK", GTK_RESPONSE_OK, "Annuler", GTK_RESPONSE_CANCEL, NULL); //********************************************************* //interface de la denêtre des paramètres de continuité //********************************************************* //Glossaire GtkWidget* frameConti = NULL; GtkWidget* tableConti = NULL; GtkWidget* LabelConti1= NULL; GtkWidget* LabelConti2= NULL; GtkWidget* LabelConti3= NULL; GtkWidget* LabelConti4= NULL; GtkWidget* LabelConti5= NULL; //mise en page des widgets //Formalisation du texte frameConti = gtk_frame_new (""); tableConti = gtk_table_new(6, 3, TRUE); //labels LabelConti1 = gtk_label_new("Resistance min :"); LabelConti2 = gtk_label_new("Resistance max :"); LabelConti3 = gtk_label_new("Courant de mesure :"); LabelConti4 = gtk_label_new("Tension max :"); LabelConti5 = gtk_label_new("Temps d'application :"); //entrys EntryConti1 = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(EntryConti1), continuite.Conti1); EntryConti2 = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(EntryConti2), continuite.Conti2); EntryConti3 = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(EntryConti3), continuite.Conti3); EntryConti4 = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(EntryConti4), continuite.Conti4); EntryConti5 = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(EntryConti5), continuite.Conti5); //Placement des éléments dans le tableau gtk_table_attach_defaults(GTK_TABLE(tableConti), LabelConti1, 0, 2, 0, 1); gtk_table_attach_defaults(GTK_TABLE(tableConti), EntryConti1, 2, 3, 0, 1); gtk_table_attach_defaults(GTK_TABLE(tableConti), LabelConti2, 0, 2, 1, 2); gtk_table_attach_defaults(GTK_TABLE(tableConti), EntryConti2, 2, 3, 1, 2); gtk_table_attach_defaults(GTK_TABLE(tableConti), LabelConti3, 0, 2, 2, 3); gtk_table_attach_defaults(GTK_TABLE(tableConti), EntryConti3, 2, 3, 2, 3); gtk_table_attach_defaults(GTK_TABLE(tableConti), LabelConti4, 0, 2, 3, 4); gtk_table_attach_defaults(GTK_TABLE(tableConti), EntryConti4, 2, 3, 3, 4); gtk_table_attach_defaults(GTK_TABLE(tableConti), LabelConti5, 0, 2, 4, 5); gtk_table_attach_defaults(GTK_TABLE(tableConti), EntryConti5, 2, 3, 4, 5); //Hiérarchie des composants graphiques gtk_container_add(GTK_CONTAINER (frameConti), tableConti); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(FenetreConti)->vbox),frameConti); gtk_widget_show_all(FenetreConti); //Affichage de la fenetre switch(gtk_dialog_run(GTK_DIALOG(FenetreConti))) { case GTK_RESPONSE_OK: continuite.Conti1 = g_locale_to_utf8(gtk_entry_get_text(GTK_ENTRY(EntryConti1)),-1, NULL, NULL, NULL); continuite.Conti2 = g_locale_to_utf8(gtk_entry_get_text(GTK_ENTRY(EntryConti2)),-1, NULL, NULL, NULL); continuite.Conti3 = g_locale_to_utf8(gtk_entry_get_text(GTK_ENTRY(EntryConti3)),-1, NULL, NULL, NULL); continuite.Conti4 = g_locale_to_utf8(gtk_entry_get_text(GTK_ENTRY(EntryConti4)),-1, NULL, NULL, NULL); continuite.Conti5 = g_locale_to_utf8(gtk_entry_get_text(GTK_ENTRY(EntryConti5)),-1, NULL, NULL, NULL); break; default: continuite.Conti1 = "default"; continuite.Conti2 = "default"; continuite.Conti3 = "default"; continuite.Conti4 = "default"; continuite.Conti5 = "default"; break; } gtk_widget_destroy(FenetreConti); } //**************************************************************************** //Traitement du bouton des paramètres d'isolement //**************************************************************************** void TraitementBoutonIso(GtkWidget* pWidget, gpointer data) { //Glossaire des widgets graphiques de TraitementBoutonIso GtkWidget* FenetreIso; GtkWidget* FenetreParent; //Creation de la fenetre de selection FenetreIso = gtk_dialog_new_with_buttons( "Parametres d'isolement", GTK_WINDOW(FenetreParent), GTK_DIALOG_DESTROY_WITH_PARENT, "OK", GTK_RESPONSE_OK, "Annuler", GTK_RESPONSE_CANCEL, NULL); //********************************************************* //interface de la denêtre des paramètres d'isolement //********************************************************* //Glossaire GtkWidget* frameIso = NULL; GtkWidget* tableIso = NULL; GtkWidget* LabelIso1= NULL; GtkWidget* LabelIso2= NULL; GtkWidget* LabelIso3= NULL; GtkWidget* LabelIso4= NULL; GtkWidget* LabelIso5= NULL; //mise en page des widgets //Formalisation du texte frameIso = gtk_frame_new (""); tableIso = gtk_table_new(6, 3, TRUE); //labels LabelIso1 = gtk_label_new("Resistance min :"); LabelIso2 = gtk_label_new("Tension d'isolement :"); LabelIso3 = gtk_label_new("Courant de claquage :"); LabelIso4 = gtk_label_new("Temps de montee :"); LabelIso5 = gtk_label_new("Temps d'application :"); //entrys EntryIso1 = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(EntryIso1), isolement.Iso1); EntryIso2 = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(EntryIso2), isolement.Iso2); EntryIso3 = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(EntryIso3), isolement.Iso3); EntryIso4 = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(EntryIso4), isolement.Iso4); EntryIso5 = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(EntryIso5), isolement.Iso5); //Placement des éléments dans le tableau gtk_table_attach_defaults(GTK_TABLE(tableIso), LabelIso1, 0, 2, 0, 1); gtk_table_attach_defaults(GTK_TABLE(tableIso), EntryIso1, 2, 3, 0, 1); gtk_table_attach_defaults(GTK_TABLE(tableIso), LabelIso2, 0, 2, 1, 2); gtk_table_attach_defaults(GTK_TABLE(tableIso), EntryIso2, 2, 3, 1, 2); gtk_table_attach_defaults(GTK_TABLE(tableIso), LabelIso3, 0, 2, 2, 3); gtk_table_attach_defaults(GTK_TABLE(tableIso), EntryIso3, 2, 3, 2, 3); gtk_table_attach_defaults(GTK_TABLE(tableIso), LabelIso4, 0, 2, 3, 4); gtk_table_attach_defaults(GTK_TABLE(tableIso), EntryIso4, 2, 3, 3, 4); gtk_table_attach_defaults(GTK_TABLE(tableIso), LabelIso5, 0, 2, 4, 5); gtk_table_attach_defaults(GTK_TABLE(tableIso), EntryIso5, 2, 3, 4, 5); //Hiérarchie des composants graphiques gtk_container_add(GTK_CONTAINER (frameIso), tableIso); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(FenetreIso)->vbox),frameIso); gtk_widget_show_all(FenetreIso); //Affichage de la fenetre switch(gtk_dialog_run(GTK_DIALOG(FenetreIso))) { case GTK_RESPONSE_OK: isolement.Iso1 = g_locale_to_utf8(gtk_entry_get_text(GTK_ENTRY(EntryIso1)),-1, NULL, NULL, NULL); isolement.Iso2 = g_locale_to_utf8(gtk_entry_get_text(GTK_ENTRY(EntryIso2)),-1, NULL, NULL, NULL); isolement.Iso3 = g_locale_to_utf8(gtk_entry_get_text(GTK_ENTRY(EntryIso3)),-1, NULL, NULL, NULL); isolement.Iso4 = g_locale_to_utf8(gtk_entry_get_text(GTK_ENTRY(EntryIso4)),-1, NULL, NULL, NULL); isolement.Iso5 = g_locale_to_utf8(gtk_entry_get_text(GTK_ENTRY(EntryIso5)),-1, NULL, NULL, NULL); break; default: isolement.Iso1 = "default"; isolement.Iso2 = "default"; isolement.Iso3 = "default"; isolement.Iso4 = "default"; isolement.Iso5 = "default"; break; } gtk_widget_destroy(FenetreIso); } void TraitementBoutonClose(GtkWidget* pWidget, GtkWidget* FenetrePrincipale) { gtk_widget_destroy(FenetrePrincipale); } -
generateur.cpp:
#include "generateur.h" int traitementFichierDesConnections(char * cheminFichierFil, typeTableauConnection tableauConnections); void TraitementBoutonGen(GtkWidget* pWidget, gchar* cheminFichierFil, gchar* cheminFichierPrf, Continuite continuite, Isolement isolement) { FILE* fichierTest = fopen("test", "w+"); cheminFichierFil = g_locale_to_utf8( "C:\\Documents and Settings\\jfaure\\Bureau\\stage1\\GenerateurCodeWinpass5000\\exemple.FIL", -1, NULL, NULL, NULL); cheminFichierPrf = g_locale_to_utf8( "C:\\Documents and Settings\\jfaure\\Bureau\\stage1\\GenerateurCodeWinpass5000\\exemple.PRF", -1, NULL, NULL, NULL); //*********************************************************************************************************** //fichier FIL //*********************************************************************************************************** int nb_connections; typeTableauConnection tableauConnections; nb_connections = traitementFichierDesConnections(cheminFichierFil, tableauConnections); int i; for(i = 0; i < nb_connections; i++) { fprintf(fichierTest,"\n%s : %s",tableauConnections[i].nomConnecteur, tableauConnections[i].contact); } //*********************************************************************************************************** //fichier PRF //*********************************************************************************************************** typeTableauDefinitionConnecteur tableauDefinitionConnecteur; int ligneligne = traitementFichierDefinitionConnecteurs(cheminFichierPrf, tableauDefinitionConnecteur); int it; fprintf(fichierTest,"\n\ndescription des connecteurs : \n"); for(it = 0; it < ligneligne; it++) { fprintf(fichierTest,"\n%s : %s",tableauDefinitionConnecteur[it].nomConnecteur, tableauDefinitionConnecteur[it].typeConnecteur); } int fclose(FILE* fichierTest); //**************************************************************** //Affichage du message de succès de la génération du fichier //**************************************************************** GtkWidget* FenetreGeneration = NULL; GtkWidget* tableGen = NULL; GtkWidget* LabelSucces = NULL; gchar* TexteSucces = NULL; GtkWidget* BoutonOK = NULL; FenetreGeneration = gtk_dialog_new(); tableGen = gtk_table_new(2, 6, TRUE); gtk_window_set_title(GTK_WINDOW(FenetreGeneration), "Generation accomplie"); TexteSucces =g_locale_to_utf8( "Génération du fichier accomplie avec succès", -1, NULL, NULL, NULL); LabelSucces = gtk_label_new (TexteSucces); gtk_table_attach_defaults(GTK_TABLE(tableGen), LabelSucces, 1, 5, 0, 1); BoutonOK = gtk_button_new_with_label("OK"); gtk_signal_connect_object (GTK_OBJECT (BoutonOK), "clicked", GTK_SIGNAL_FUNC (gtk_main_quit), FenetreGeneration); gtk_table_attach_defaults(GTK_TABLE(tableGen), BoutonOK, 2, 4, 1, 2); gtk_container_add (GTK_CONTAINER (GTK_DIALOG(FenetreGeneration)->vbox), tableGen); gtk_widget_show_all (FenetreGeneration); } //************************************************************************************************************** int tailleLignesFichier (FILE* fichier) { int taille = 0; while( fgets (chaine, TAILLE_MAX, fichier) != NULL) { taille++; } //remise du curseur au début du fichier fseek(fichier, 0, SEEK_SET); return taille; } //************************************************************************************************************** int tailleLigneDescConnecteur (FILE* fichier) { int ligne=0; int trouve=0; char buffer[TAILLE_MAX]; while(fgets(buffer, sizeof buffer, fichier)) { ligne++; if(strstr(buffer,"EQUIPEMENT DE BASE")) { trouve=1; break; } } if(trouve) { //remise du curseur au début du fichier fseek(fichier, 0, SEEK_SET); return ligne - 1; } else { return 0; } } //************************************************************************************************************** int traitementFichierDesConnections (char * cheminFichierFil, typeTableauConnection tableauConnections) { int iLigne = 0; //itérateur pour les lignes (vérifier le 1 peut-etre 0) int i = 0; //itérateur pour les diférentes connections dans le tableau int j = 0; //itérateur pour le nombre de caractère des données récupérées int iSaut; //itérateur pour sauter les caractères indésirés int testPremiereBoucle; //booléen pour savoir si l'on doit sauter le premier caractère ou non char carac; //caractère renvoyé par les fputc //ouverture du fichier en lecture FILE* fichierFil = fopen(cheminFichierFil, "r"); if(fichierFil != NULL) { //test du nombre de lignes const int NB_LIGNES = tailleLignesFichier (fichierFil); while(iLigne < NB_LIGNES) { //******************************************* //traitement d'une ligne //******************************************* iSaut = 0; testPremiereBoucle = 1; //tant que l'on ne trouvons pas le marqueur de fin de ligne on continue le traitement while((carac=fgetc (fichierFil)) != 10)//10 étant l'entier associé au caractère "retour à la ligne" { j = 0; //on saute les renseignements qui ne nous interresent pas while(iSaut < 10) { carac = fgetc (fichierFil); //on ne valide le saut d'une colonne que lorsque l'on rencontre le caractère "|" if(carac == 124)//124 étant l'entier associé au caractère "|" { iSaut++; } } //si il s'agit de la première boucle de la ligne, on doit sauter un dernier caractère if(testPremiereBoucle == 1) { carac = fgetc (fichierFil); testPremiereBoucle = 0; } //on stocke dans le tableau le nom du connecteur while(carac != 47)//47 étant l'entier associé au caractère "/" { tableauConnections[i].nomConnecteur[j]=carac; j++; carac = fgetc (fichierFil); } carac = fgetc (fichierFil); j = 0 ; //on stocke dans le tableau le contact while(carac != 124) { tableauConnections[i].contact[j]=carac; j++; carac = fgetc (fichierFil); } i++; } iLigne++; } } else { printf("\nerreur \x85 l'ouverture du fichier %s", cheminFichierFil); } //fermeture du fichier int fclose(FILE* fichierFil); //on retourne le nombre de connections return i; } //************************************************************************************************************** int traitementFichierDefinitionConnecteurs (char * nomFichierPrf, typeTableauDefinitionConnecteur tableauDefinitionConnecteur) { long iLigne = 0; //itérateur pour les lignes int i = 0; //itérateur pour les connections int j; //itérateur pour le nombre de caractère des données récupérées char carac; //caractère renvoyé par les fputc //ouverture du fichier en lecture FILE* fichierPrf = fopen(nomFichierPrf, "r"); if(fichierPrf != NULL) { //test du nombre de lignes const int NB_LIGNES = tailleLigneDescConnecteur(fichierPrf); while(iLigne < NB_LIGNES) { //******************************************* //traitement d'une ligne //******************************************* if (fgetc (fichierPrf) != 179) { while((fgetc (fichierPrf)) != 10); } else { int iterator; //on saute les caractères intiles for (iterator = 0; iterator < 7; iterator++) { carac = fgetc(fichierPrf); } if(carac == 32) { //ligne vide donc aucun traitement } else { j = 0; while(carac != 32) { //on stocke dans le tableau le nom du connecteur tableauDefinitionConnecteur[i].nomConnecteur[j] = carac; j++; carac = fgetc (fichierPrf); } for (iterator = 0; iterator < 3; iterator++) { //on saute les caractères intiles carac = fgetc (fichierPrf); } j = 0; while(carac != 32) { //on stocke dans le tableau le nom du types du connecteur tableauDefinitionConnecteur[i].typeConnecteur[j] = carac; j++; carac = fgetc (fichierPrf); } i++; } while((fgetc (fichierPrf)) != 10); } iLigne++; } } else { printf("\nerreur \x85 l'ouverture du fichier %s", nomFichierPrf); } //fermeture du fichier int fclose(FILE* fichierPrf); //on retourne le nombre de définitions de connecteurs return i; } -
Bon je vais te faire un copier coller des 3 fichiers en 3 post, ce sera plus clair. (j'ai changé le generateur.c en generateur.cpp, et on dirait que les problèmes sont différents. (des multiples définitions maintenant.)
Et on reprend à partir de là si tu veux bien =)
Je commence tout de suite avec mon generateur.h:#ifndef generateur.h #define generateur.h #include <stdlib.h> #include <gtk/gtk.h> #include <stdio.h> #include <string.h> #define TAILLE_MAX 1000 #define TAILLE_MAX_PETIT 20 extern char chaine[TAILLE_MAX]; extern gchar* cheminFichierFil; //******************************************************************************** //Partie interface //******************************************************************************** //paramètres d'isolement typedef struct { const gchar* Iso1; const gchar* Iso2; const gchar* Iso3; const gchar* Iso4; const gchar* Iso5; } Isolement; Isolement isolement; //paramètres de continuité typedef struct { const gchar* Conti1; const gchar* Conti2; const gchar* Conti3; const gchar* Conti4; const gchar* Conti5; } Continuite; Continuite continuite; //Génère le code du programme winpass void TraitementBoutonGen(GtkWidget* pWidget, gchar* cheminFichierFil, gchar* cheminFichierPrf, Continuite continuite, Isolement isolement); //******************************************************************************** //partie générateur //******************************************************************************** //retourne le nombre de lignes d'un fichier int tailleLignesFichier (FILE* fichier); //enregistrement d'une connection typedef struct { char nomConnecteur[TAILLE_MAX_PETIT]; char contact[TAILLE_MAX_PETIT]; } connection; //création du type qui savegardera les connections typedef connection typeTableauConnection [TAILLE_MAX]; //enregistrement d'une définition de connecteur typedef struct { char nomConnecteur[TAILLE_MAX_PETIT]; char typeConnecteur[TAILLE_MAX_PETIT]; } defConnection; //création du type qui savegardera les définition des connecteurs typedef defConnection typeTableauDefinitionConnecteur [TAILLE_MAX]; //traitement d'un fichier des connections de type fichier.FIL int traitementFichierDesConnections (char * nomFichierFil, typeTableauConnection tableauConnection); //traitement d'un fichier des définition de connecteurs de type fichier.PRF int traitementFichierDefinitionConnecteurs (char * nomFichierPrf, typeTableauDefinitionConnecteur tableauDefinitionConnecteur); #endif -
J'avais mélangé tes fichiers en les recopiant, c'est pour ça que je ne retrouvais pas des définitions et les déclarations aux bons endroits. Donc ce que j'ai dit dans mon dernier message ne tient pas la route.
D'ailleurs je n'arrive plus à suivre, je ne connais plus l'état actuel de tes fichiers.
Actuellement, qu'est devenu le generateur.c ? S'il n'est plus inclus dans main.cpp, il faudrait le rebaptiser en .cpp et le mettre dans le projet.
Par ailleurs, gchar* cheminFichierFil = NULL; dans generateur.c. est une définition de variable et non pas une déclaration : cette ligne crée bien une zone mémoire pour stocker la variable. -
Désolé, je ne te suis pas vraiment là... Je ne vois pas de déclaration de gchar* cheminFichierFil = NULL; dans generateur.c.
Et j'ai changé mon generateur.h en rajoutant la ligne extern gchar* cheminFichierFil; (enfin si c'est ca que tu veux dire) c'est bien une déclaration? ou je je trompe?
Pour TraitementBoutonGen, le prototype de cette fonction ne suffit pas dans le generateur.h?
En fait, tu as raison, je ne sais pas vraiment ce qu'est la définition et la déclaration visiblement... désolé ... -
Je viens enfin de remarquer... tu as défini gchar* cheminFichierFil = NULL; dans generateur.c, mais tu ne l'as pas déclaré dans generateur.h ! Normal qu'il ne le connaisse plus si tu n'inclus pas generateur.c
idem pour TraitementBoutonGen.
Mais as-tu une conscience bien précise de ce que sont la définition et la déclaration ? C'est peut-être pour ça que tu as des problèmes avec les headers et que tu fais des include (excuse-moi) au hasard au lieu de les faire logiquement.
- 1
- 2