Thread: Passing structs to callback functions (GTK+ related)

  1. #1
    Registered User
    Join Date
    Feb 2009
    Posts
    16

    Passing structs to callback functions (GTK+ related)

    I've been working on GUI programming, using the GTK+ API. It's been great fun, though I've run into a frustrating problem I can't wrap my head around.

    I will lightly go over the GTK+ API, as I discuss my problem.

    The copy/paste functions take 2 arguments, one is the desired string to copy, and the other is the clipboard object.
    This function will execute when the user hits CTRL+C
    Code:
    void copythis(GtkWidget *w, CCP *stuff)
    {
    	gtk_text_buffer_copy_clipboard(stuff->buf, stuff->clip); 
    }
    Now, the first argument is the widget that is calling this function. When calling a function you must pass a pointer to the widget, as well as one other argument. This makes it rather difficult because my callback function requires two arguments - a string, and a clipboard object.

    Therefore I create a struct, that will allow me to hold both of these variables
    Code:
    typedef struct copycutpaste CCP;
    
    struct copycutpaste {
    	GtkTextBuffer *buf;
    	GtkClipboard *clip;
    };
    Now here are my variable initializations in the main function.
    Code:
    GtkTextBuffer *buffer;
    GtkClipboard *board;
    
    CCP copying = {buffer, board};
    CCP pasting = {buffer, board};
    CCP cutting = {buffer, board};
    Finally my callback function
    Code:
    g_signal_connect(G_OBJECT(copy), "activate", G_CALLBACK(copythis), &copying);
    "G_OBJECT(copy)" is a menu item widget. Whenever the user clicks "copy" in the menu this function will execute. "G_CALLBACK(copythis)" is the function to call on, and "&copying" is the argument that is passed.

    Now, the code compiles without warnings, however I am getting segmentation faults whenever the function "copythis" is executed. I've looked over this for so long, and I can't pick out whats wrong with it. Any help would be much appreciated, I hope I've explained it well enough. If you need clarification on any function just ask.
    Last edited by Raskalnikov; 03-20-2009 at 10:06 PM.

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    From the posted code it's not clear if you have allocated enough storage (if any) for the elements of the CCP struct?
    Did you try to isolate the program segment that is causing the segfault by running it through a debugger?

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    I've been doing a lot of gtk stuff lately and it is hard to debug. Presuming that CCP is a real struct and not a struct*, I don't see anything wrong with your set-up, altho I would include a cast with g_signal_connect (so the last argument is (gpointer*)&copying).

    What you could try is a slightly different struct containing two char pointers to make sure you have all the syntax working:

    Code:
    #include <gtk/gtk.h>
    
    typedef struct {
    	char *this;
    	char *that;
    } example;
    
    void callback_func (GtkWidget *ignored, example *test) {
    	printf("%s and %s\n",test->this, test->that);
    }
    
    
    int main(int argc, char *argv[]) {
    	char this[]="this", that[]="that";
    	example test;
    	GtkWidget *window, *button;
    	
    	test.this=this;
    	test.that=that;
    
        	gtk_init (&argc, &argv);
    	
        	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
        	g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK (gtk_main_quit), NULL);
        	g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL);
    
    	
    	button = gtk_button_new_with_label("click here");
    	gtk_container_add(GTK_CONTAINER(window),button);
        	g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback_func), (gpointer*)&test);
    	
    	gtk_widget_show_all(window);
    
        	gtk_main ();
        	return 0;
    }
    Since that all works, then trying writing callbacks passing your struct, but which only uses one of the elements, to see if it isn't something related to that.

    If you include statements like this on every other line in the callback:
    Code:
    g_print("callback() line1, myvar=%d\n",myvar); fflush(stdout);
    You should be able to get a good idea of where something is going wrong. It is tedious, but you cannot debug gtk stuff in a normal degbugger very effectively, so it might be your only choice.

    There is also gtkforums
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with passing structs to a function.
    By darsh1120 in forum C Programming
    Replies: 7
    Last Post: 03-11-2008, 04:36 AM
  2. Passing members of structs to functions
    By CV3 in forum C Programming
    Replies: 6
    Last Post: 09-23-2004, 01:56 PM
  3. Passing data/pointers between functions #2
    By TankCDR in forum C Programming
    Replies: 1
    Last Post: 11-02-2001, 09:49 PM
  4. Passing data/pointers between functions
    By TankCDR in forum C Programming
    Replies: 1
    Last Post: 11-02-2001, 12:59 AM
  5. passing functions with variable
    By itld in forum C++ Programming
    Replies: 1
    Last Post: 10-30-2001, 11:43 PM