gtk_label_set_text - segmentation fault?



  • hallo nochmal,

    ich bin auf ein weiteres problem gestoßen, das ich mir jedoch nicht erklären kann. von gtk möchte ich die timer-funktion benutzen und auf einem label den timerstand anzeigen.
    meine funktion sieht so aus:

    int timer_starten()
    {
      gchar temp;
    
      while(1)
      {
        if(musicPlaying == 0)
        {
          pthread_exit(timer_starten);
          break;
        }
    
        if(g_timer_elapsed(timer,0)-temp >= 1)
        {
    
          printf("%lf\n",g_timer_elapsed(timer,0)); /* GEHT */
          gtk_label_set_text(GTK_LABEL(l_titel),temp); /* GEHT NICHT */
          temp = g_timer_elapsed(timer,0);
    
        }
    
        SDL_Delay(1000);
      }
    
      return 0;
    }
    

    der timer "timer" ist erstellt und gestartet.
    gtk_label_set_text funktioniert gar nicht, nach einer sekunde stürzt das programm ab (segmentation fault). wenn ich die zeile jedoch auskommentiere, läuft printf wunderbar sekunde für sekunde durch! anscheinend kann temp in printf, aber nicht in gtk_label_set_text eingefügt werden...doch woran liegt das? bei einem statischen wert, wie gtk_label_set_text(GTK_LABEL(l_titel),"hallo"); läuft das programm hingegen wieder...

    irgendwas ist da faul. wäre nett, wenn mir jemand nen ratschlag geben könnte 🙂

    gruß
    martin

    nachtrag: gdb meldet:
    Program received signal SIGSEGV, Segmentation fault.
    [Switching to Thread 0x49b1b70 (LWP 9730)]
    0x00b20f6b in strlen () from /lib/tls/i686/cmov/libc.so.6



  • ist ja logisch 😉

    gtk_label_set_text() erwartet als 2. parameter ein gchar*
    g_timer_elapsed() gibt dir ein gdouble zurück

    lösung wandle den rückgabe wert von g_timer_elapsed() in einen string also
    double zu char*

    z.b.

    char buffer[30];
    sprintf(buffer,"%f",g_timer_elapsed(...));
    gtk_label_set_text(...,buffer);
    

    lg lolo



  • wow, das funktioniert wirklich, vielen dank! ich hab's mit
    gtk_label_set_text(GTK_LABEL(l_titel),(char*)temp) versucht, doch ohne erfolg. wandelt (char*) o.ä. nicht auch den wert dahinter um?

    sry, jetzt tritt das nächste problem auf:
    das label verändert seinen inhalt nur spontan mal. nur wenn ich ständig die maus bewege, aktualisiert sich das label nebenbei auch immer. bei google hab ich gelesen, man könne g_main_context_iteration(NULL, FALSE); benutzen. doch dann bekomme ich ~20 mal die meldung
    GLib-WARNING **: g_main_context_prepare(): main loop already active in another thread
    und dann einmal die meldung
    GLib:ERROR:/build/buildd/glib2.0-2.22.3/glib/gmain.c:1911:g_main_dispatch: assertion failed: (source)
    wonach das programm abstürzt 😕

    dabei konnte google mir dann nicht mehr helfen...

    gruß
    martin



  • versuch mal in z.19

    gtk_widget_queue_draw(GTK_WIDGET(l_titel));
    

    und lass das "g_main_context_iteration(NULL, FALSE);" weg



  • das funkioniert leider nicht. das label aktualisiert sich mit gtk_widget_queue_draw(GTK_WIDGET(l_titel)); nur wenn man die maus bewegt.



  • also ich hab keine wie fast immer keinen plan, das einzige was ich dir anbieten kann ist ein kleiner test case

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <time.h>
    #include <gtk/gtk.h>
    #include <glib.h>
    #include <pthread.h>
    #include <sys/time.h>
    #define YES_IT_IS    (1)
    #define NO_IT_IS_NOT (0)
    
    #define MICRO_IN_SEC 1000000.00
    double microtime(){
    	struct timeval tp = {0};
    	gettimeofday(&tp, NULL);
    	return (double)(tp.tv_sec + tp.tv_usec / MICRO_IN_SEC);
    }
    
    void destroy (GtkWidget *widget, gpointer data)
    {
      gtk_main_quit ();
    }
    
    void *argument_thread (void *label)
    {
      char tt[30];
      for (;;){
    	gdk_threads_enter ();
            sprintf(tt,"%lf",microtime());
    	gtk_label_set_text (GTK_LABEL (label), tt);
    	gdk_threads_leave ();
      }
      return NULL;
    }
    
    int main (int argc, char *argv[])
    {
      GtkWidget *window;
      GtkWidget *label;
      pthread_t yes_tid;
    
      /* init threads */
      g_thread_init (NULL);
      gdk_threads_init ();
      gdk_threads_enter ();
    
      /* init gtk */
      gtk_init(&argc, &argv);
    
      /* create a window */
      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    
      gtk_signal_connect (GTK_OBJECT (window), "destroy",
    		      GTK_SIGNAL_FUNC (destroy), NULL);
    
      gtk_container_set_border_width (GTK_CONTAINER (window), 10);
    
      /* create a label */
      label = gtk_label_new ("And now for something completely different ...");
      gtk_container_add (GTK_CONTAINER (window), label);
    
      /* show everything */
      gtk_widget_show (label);
      gtk_widget_show (window);
    
      /* create the thread */
      pthread_create (&yes_tid, NULL, argument_thread, label);
    
      /* enter the GTK main loop */
      gtk_main ();
      gdk_threads_leave ();
    
      return 0;
    }
    

    oder du postest mal deinen source code dann kann ich ja mal schauen ob ich da was machen kann 😕 hoffe das hilft ein bischen, falls du ne lösung hast post die bitte, interessiert mich auch 🙂


Anmelden zum Antworten