Search code examples
cgtk3

Unable to Pass a Structure of User Data to GTK Callbacks


Although similar questions have been answered regarding this scenario, I'm stuck.

I'm using a structure to pass data to a GTK callback. The structure is defined as

typedef struct List_Stores {
    GSList * list_store_master; 
    GSList * list_store_temporary; 
    List_Builder_Struct * list_builder_struct; 
} List_Store_Struct;

I declare the structure in a function.

List_Store_Struct list_store_struct;

This structure is passed by reference to a function that makes buttons in a box.

GtkWidget *accounts_buttons_hbox = make_buttons(&list_store_struct);

Inside make_buttons I connect a signal using

g_signal_connect(button, "clicked", G_CALLBACK(revert), list_store_struct);

Inside the function revert I want to examine the contents of the structure.

static void revert(GtkWidget* widget, gpointer data) {
    List_Store_Struct* list_store_struct = (List_Store_Struct *) data;

    /* The following lines point to nothing or give the debugger message Cannot access memory at address 0xblahblah */
    GtkListStore * list_store = (list_store_struct->list_builder_struct)->list_store;
    GSList * list_store_master = list_store_struct->list_store_master;
    GSList * list_store_temporary = list_store_struct->list_store_temporary; 
}

The debugger shows that the pointer list_store_struct points to an empty memory location; I cannot access the structure's members. Furthermore, attempting to access the structure's members results in a segmentation fault.

What is the correct way to pass this structure to the callback so that I can access the structure's members?


Solution

  • As noted in my original post, I was attempting to pass to a callback function a pointer to a user-defined structure List_Store_Struct. Try as I could, the callback was not able to properly cast the passed gpointer to a pointer to List_Store_Struct.

    I later learned that GTK provides a type GPtrArray. While possibly not designed for my use case, passing a void pointer to an instance of GPtrArray cleanly casts in the callback, and I was able to access the data at the subsidiary pointers' locations.