[C+GTK] Structure qui ne contient plus rien ???

Structure qui ne contient plus rien ??? [C+GTK] - C - Programmation

Marsh Posté le 25-04-2007 à 17:32:33    

Salut tlm,
dans le cadre d'un soft de chat en C avec GTK, je voudrais envoyer une structure du fichier main vers un client, sans y parvenir; Je m'explique.

 

Dans la version non graphique, je dispose d'un fichier main, avec dans le main :

 
Citation :


 reply message;
 strcpy(message.pseudo,"Bourreau" );
 strcpy(message.msg,"texte" );
 pthread_create(&thread2, NULL, client, (void *) &message);

 

Avec comme structure pour reply :

Citation :


typedef struct {char pseudo[10] ; char msg[250] ;} reply ;

 

Dans sa version non graphique, tout marche impec. Le main cré un thread client et lui envoie le message, le client saura le lire et l'envoyer à qqn sur le réseau.

 

Voilà la gueule du client :

Citation :


void * client(void * arg)
{
 sleep(1);
 char *host = "127.0.0.1";
 enum clnt_stat stat;
 
 reply* message;
 message = (reply*) arg;

 

 printf ("%s et  %s\n",message->pseudo,message->msg);
 
 
  stat = callrpc(host,PROGNUM,VERSNUMET,PROC_UN,(xdrproc_t) xdr_txt_in, (char *) message,(xdrproc_t) xdr_txt_out, (char *) message) ;
...

 


Seulement dans sa version GTK, rien à faire. Le changement :
le pthread_create n'est plus dans le main directement, mais dans une fonction du main, celle qui correspond au click sur un bouton.

 

Le reste est identique, le client est totalement inchangé. Seulement voilà, le client ne sait du coup plus recup le contenu de la structure et laisse les champs désespérement vides :/

 

Savez-vous ou se situe le problème ? Pq le fait d'appeler le client par une fonction du main et non plus dans le main entraine une perte des données de la structure ?

 

D'avance merci :(


Message édité par Bourreau le 25-04-2007 à 17:32:52
Reply

Marsh Posté le 25-04-2007 à 17:32:33   

Reply

Marsh Posté le 25-04-2007 à 17:36:23    

le tread n'est pas détruit à la fin de la fonction (question con j'en sais rien :/)


---------------
Blog photo/récits activités en montagne http://planetcaravan.net
Reply

Marsh Posté le 25-04-2007 à 17:40:02    

non, je viens de tenter de commentariser toutes les lignes de fermeture de threads et de vidage de buffer, aucun changement :/

Reply

Marsh Posté le 25-04-2007 à 18:12:10    

Bourreau a écrit :

non, je viens de tenter de commentariser toutes les lignes de fermeture de threads et de vidage de buffer, aucun changement :/


Bah, il y a un bug dans ton code gtk. Sans voir le code, comment en dire plus ?
 
Ton code est inutilement compliqué
 

Code :
  1. pthread_create(&thread2, NULL, client, &message);


...
 

Code :
  1. void * client (void * arg)
  2. {
  3.    reply* message = arg;
  4.    if (arg != NULL)
  5.    {
  6.        char *host = "127.0.0.1";
  7.        enum clnt_stat stat;
  8.      
  9.        sleep(1); /* est-ce bien necessaire ? */
  10.        ...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 25-04-2007 à 21:49:38    

Merci pour ton aide, j'ai essayé tes modifs, aucun changement. Le sleep est en effet superflus ;)
 
Voilà le code complet du fichier comportant le main :
 

Code :
  1. #include <stdlib.h>
  2. #include <gtk/gtk.h>
  3. #include "include.h"
  4. void Sending (GtkWidget *pWidget, gpointer *data)
  5. {
  6. GtkWidget *pDialog;
  7. GtkWidget *pTextView;
  8. GtkTextBuffer* pTextBuffer;
  9. GtkTextIter iStart;
  10. GtkTextIter iEnd;
  11. gchar* sBuffer;
  12. pthread_t thread2;
  13. reply message;
  14. pTextView = GTK_WIDGET(data);
  15. pTextBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(pTextView));
  16. gtk_text_buffer_get_start_iter(pTextBuffer, &iStart);
  17. gtk_text_buffer_get_end_iter(pTextBuffer, &iEnd);
  18. sBuffer = gtk_text_buffer_get_text(pTextBuffer, &iStart, &iEnd, TRUE);
  19. // a chaque printf ci-dessous le contenu des variable existe, il n'est à zéro qu'apres transmission
  20. printf ("%s\n",sBuffer);
  21. strcpy(message.pseudo,"Bourreau" );
  22. strcpy(message.msg,"texte" );
  23. printf("%s || %s\n",message.pseudo,message.msg);
  24. printf ("%s\n",sBuffer);
  25.  if (pthread_create(&thread2, NULL, client, &message))
  26.  {
  27.   fprintf(stderr, "error creating a new thread (client) \n" );
  28.  }
  29. printf("%s ||| %s\n",message.pseudo,message.msg);
  30. g_free(sBuffer);
  31. pthread_detach(thread2);
  32. }
  33. int main(int argc, char* argv[])
  34. {
  35. // Partie chat normal
  36. pthread_t thread1;
  37. int i;
  38. char txt[250];
  39. if(argc!=2)
  40.         {
  41.  printf("Usage: %s <nickname>\n", argv[0]);
  42.  return(-1);
  43. }
  44. if (pthread_create(&thread1, NULL, server, NULL/*(void *)(buf)*/)) {
  45.  fprintf(stderr, "error creating a new thread (server) \n" );
  46.    return (-1);
  47.  }
  48. // Partie GTK
  49. GtkWidget* pWindow;
  50. GtkWidget* pBox;
  51. GtkWidget* pTextView;
  52. GtkWidget* pButton;
  53. gtk_init(&argc, &argv);
  54. pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  55. gtk_window_set_default_size(GTK_WINDOW(pWindow), 320, 200);
  56. gtk_window_set_title(GTK_WINDOW(pWindow), "OBMSN" );
  57. g_signal_connect(G_OBJECT(pWindow), "destroy", G_CALLBACK(gtk_main_quit), NULL);
  58.      pLabel = gtk_label_new(NULL);
  59.      gtk_box_pack_start(GTK_BOX(pVBox), pLabel, FALSE, FALSE, 0);
  60. pBox = gtk_vbox_new(FALSE, 5);
  61. gtk_container_add(GTK_CONTAINER(pWindow), pBox);
  62. pTextView = gtk_text_view_new();
  63. gtk_box_pack_start(GTK_BOX(pBox), pTextView, TRUE, TRUE, 0);
  64. pButton=gtk_button_new_with_label("Send" );
  65. gtk_box_pack_start(GTK_BOX(pBox),pButton,FALSE,FALSE,0);
  66. g_signal_connect(G_OBJECT(pButton), "clicked", G_CALLBACK(Sending), (gpointer) pTextView);
  67. gtk_widget_show_all(pWindow);
  68. gtk_main();
  69. return EXIT_SUCCESS;
  70. pthread_detach(thread1);
  71. pthread_exit(NULL);
  72. return 0;
  73. }


 
 
En esperant que ca puisse aider :/ Merci d'avance.

Message cité 1 fois
Message édité par Bourreau le 25-04-2007 à 21:50:06
Reply

Marsh Posté le 26-04-2007 à 09:07:56    

Bourreau a écrit :

Merci pour ton aide, j'ai essayé tes modifs, aucun changement. Le sleep est en effet superflus ;)
 
Voilà le code complet du fichier comportant le main :
 


Il manque le "include.h"
 
J'ai reconstitué ceci :  

Code :
  1. #include <stdlib.h>
  2. #include <gtk/gtk.h>
  3. #if 0
  4. #include "include.h"
  5. #else
  6. #include <pthread.h>
  7. #include <stdio.h>
  8. typedef struct
  9. {
  10.    char pseudo[10];
  11.    char msg[250];
  12. }
  13. reply;
  14. #endif
  15. #ifdef WIN32
  16. #include <windows.h>
  17. #define msleep(ms) Sleep(ms)
  18. #else
  19. #define msleep(ms) usleep((ms)*1000)
  20. #endif
  21. void *client (void *arg)
  22. {
  23.    reply *message = arg;
  24.    if (arg != NULL)
  25.    {
  26.       printf ("client : %s et  %s\n", message->pseudo, message->msg);
  27.       msleep (1000);
  28.       printf ("client : end\n" );
  29.    }
  30.    return NULL;
  31. }
  32. void *server (void *arg)
  33. {
  34.    printf ("server\n" );
  35.    msleep (1000);
  36.    printf ("server : end\n" );
  37.    (void) arg;
  38.    return NULL;
  39. }
  40. void Sending (GtkWidget * pWidget, gpointer * data)
  41. {
  42.    /*
  43.       GtkWidget *pDialog;
  44.     */
  45.    GtkWidget *pTextView;
  46.    GtkTextBuffer *pTextBuffer;
  47.    GtkTextIter iStart;
  48.    GtkTextIter iEnd;
  49.    gchar *sBuffer;
  50.    pthread_t thread2;
  51.    reply message;
  52.    pTextView = GTK_WIDGET (data);
  53.    pTextBuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pTextView));
  54.    gtk_text_buffer_get_start_iter (pTextBuffer, &iStart);
  55.    gtk_text_buffer_get_end_iter (pTextBuffer, &iEnd);
  56.    sBuffer = gtk_text_buffer_get_text (pTextBuffer, &iStart, &iEnd, TRUE);
  57. // a chaque printf ci-dessous le contenu des variable existe, il n'est à zéro qu'apres transmission
  58.    printf ("%s\n", sBuffer);
  59.    strcpy (message.pseudo, "Bourreau" );
  60.    strcpy (message.msg, "texte" );
  61.    printf ("%s || %s\n", message.pseudo, message.msg);
  62.    printf ("%s\n", sBuffer);
  63.    if (pthread_create (&thread2, NULL, client, &message))
  64.    {
  65.       fprintf (stderr, "error creating a new thread (client) \n" );
  66.    }
  67.    printf ("%s ||| %s\n", message.pseudo, message.msg);
  68.    g_free (sBuffer);
  69.    pthread_detach (thread2);
  70. }
  71. int main (int argc, char *argv[])
  72. {
  73. // Partie chat normal
  74.    pthread_t thread1;
  75.    /*
  76.       char txt[250];
  77.     */
  78.    if (argc != 2)
  79.    {
  80.       printf ("Usage: %s <nickname>\n", argv[0]);
  81.       return (-1);
  82.    }
  83.    if (pthread_create (&thread1, NULL, server, NULL /*(void *)(buf) */ ))
  84.    {
  85.       fprintf (stderr, "error creating a new thread (server) \n" );
  86.       return (-1);
  87.    }
  88. // Partie GTK
  89.    GtkWidget *pWindow;
  90.    GtkWidget *pBox;
  91.    GtkWidget *pTextView;
  92.    GtkWidget *pButton;
  93.    GtkWidget *pLabel;           /* -ed- ajoute */
  94.    GtkWidget *pVBox;            /* -ed- ajoute */
  95.    gtk_init (&argc, &argv);
  96.    pWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  97.    gtk_window_set_default_size (GTK_WINDOW (pWindow), 320, 200);
  98.    gtk_window_set_title (GTK_WINDOW (pWindow), "OBMSN" );
  99.    g_signal_connect (G_OBJECT (pWindow), "destroy",
  100.                      G_CALLBACK (gtk_main_quit), NULL);
  101.    pLabel = gtk_label_new (NULL);
  102.    gtk_box_pack_start (GTK_BOX (pVBox), pLabel, FALSE, FALSE, 0);
  103.    pBox = gtk_vbox_new (FALSE, 5);
  104.    gtk_container_add (GTK_CONTAINER (pWindow), pBox);
  105.    pTextView = gtk_text_view_new ();
  106.    gtk_box_pack_start (GTK_BOX (pBox), pTextView, TRUE, TRUE, 0);
  107.    pButton = gtk_button_new_with_label ("Send" );
  108.    gtk_box_pack_start (GTK_BOX (pBox), pButton, FALSE, FALSE, 0);
  109.    g_signal_connect (G_OBJECT (pButton), "clicked", G_CALLBACK (Sending),
  110.                      (gpointer) pTextView);
  111.    gtk_widget_show_all (pWindow);
  112.    gtk_main ();
  113.    return EXIT_SUCCESS;
  114.    pthread_detach (thread1);
  115.    pthread_exit (NULL);
  116.    return 0;
  117. }


Il subsiste des warnings inquiétants :  
 


main.c:51: warning: unused parameter 'pWidget'
main.c: In function `main':
main.c:115: warning: 'pVBox' might be used uninitialized in this function



---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 26-04-2007 à 16:54:48    

Merci bcp pour ton aide. Ce n'était pas encore exactement ca, mais je m'en suis inspiré et maintenant ca fonctionne, la structure n'est plus perdue.
 
Mais j'ai un problème qui subsiste, j'avais pas mis cette partie dans le code ici, mais j'ai créé au dessus de la zone de saisie de texte une zone de texte de type :
 
   pLabel = gtk_label_new(NULL);
 
Tjs dans l'optique du chat, cette zone doit etre mise à jour avec le contenu du chat. Seulement voilà, impossible de mettre à jour cette zone. J'ai bien récupéré une fonction de refresh, mais meme en modifiant cette zone dans le ficheir du main et en faisant un refresh derriere, ca ne fonctionne pas.
 
J'ai ca :
 
fonction de refresh :

Code :
  1. void redraw(GtkWidget * widget) /* le widget à rafraîchir */
  2. {
  3.     gtk_widget_queue_draw(GTK_WIDGET(widget)); /* demande son rafraichissement immédiat */
  4. }


 
Le Label du main :

Code :
  1. pLabel = gtk_label_new(NULL);
  2.      gtk_box_pack_start(GTK_BOX(pBox), pLabel, TRUE, TRUE, 0);
  3.         gtk_label_set_text(GTK_LABEL(pLabel), received);


 
Donc j'ai déclaré le widget du label en static tout en haut, les 3 lignes du label sont mises dans le main, et le "received" (contenu du chat, à figurer dans le label) est modifié dans une fonction, et est suivi par un :
 redraw(pLabel);
 
Mais rien ne semble s'afficher :/ Je fais qqch de mal ? Ne s'agit-il pas d'un label pour faire ce que je veux ? Dois-je faire le refresh autrement ?
 
 
 
Une fois de plus merci d'avance pour vos réponses :jap:

Reply

Marsh Posté le 26-04-2007 à 17:07:52    

Bourreau a écrit :

Mais j'ai un problème qui subsiste, j'avais pas mis cette partie dans le code ici, mais j'ai créé au dessus de la zone de saisie de texte une zone de texte de type :

Code :
  1. pLabel = gtk_label_new(NULL);




Je ne connais pas assez GTK+ pour pouvoir t'aider. Il faudrait voir les spécialistes ici :  
 
http://www.developpez.net/forums/f [...] .php?f=390


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 26-04-2007 à 17:15:48    

Comment impossible de mettre à jour ? Je comprends rien à ce que tu fais avec ta label. Utilise une GtkTextView plutot que d'empiler les widgets ...
 
ton empilage doit marcher très bien, il faut juste regaire un show/show_all ...

Reply

Marsh Posté le 26-04-2007 à 17:41:38    

Il ne se remet jamais à jour. Comme dit précedemment, dans le main je déclare mon label et veut qu'il contienne en permanence le contenu de ma variable "received".
 
Mais le problème est qu'il garde en permanence le contenu initial de received, au moment de la création dans le main. Si received contient texte, mon label affichera toujours texte. S'il est vide, il ne contiendra jamais rien, malgré mes refresh et mon show_all.
 
Je voudrais que, si le "received" est modifié dans une fonction, le label soit mis à jour, mais je n'y parviens pas :(

Reply

Marsh Posté le 26-04-2007 à 17:41:38   

Reply

Marsh Posté le 26-04-2007 à 20:21:23    

je crois que j'ai trouvé mon erreur, je regarde ca. :jap:

Reply

Marsh Posté le 28-04-2007 à 15:04:02    

tu ne dois faire aucun refresh ni show. Juste des set_text. Si ça ne marche pas, c'est que problème est ailleurs.

Reply

Sujets relatifs:

Leave a Replay

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