GTK_TOGGLE_BUTTON()宏期间的段错误。更改复选框状态后指针值已更改

时间:2019-05-10 05:53:28

标签: c pointers checkbox segmentation-fault gtk3

我正在尝试使用Glade和GTK + 3创建GUI程序,以将设置数据和配置数据写入自定义微芯片。我正在尝试实现一项功能,以将以前的配置保存/加载到我的GUI中。保存到文件并加载后,我的一些回调函数现在引起了段错误。一个示例是“全局启用”复选框的回调。

我目前正在尝试从文件中读取数据,并使用该数据来更新GUI的状态(以及用于配置IC的全局变量)。我如下更新我的复选框:

$http({method: "PUT", url: URL}).
        then(
           function(response) {
        }, function(response) {
      });

我遇到的问题是,加载新配置(即触发我的Load_File_Button回调)后,我的GEN_CB回调在此行上触发了段错误:

/* Global widget handles */
GtkWidget* GEN_CB_h;
GtkWidget* Neg_Pol_CB_h;
GtkWidget* Save_File_Name_Box_h;
GtkWidget* Save_File_Button_h:
GtkWidget* Load_File_Button_h;
//more widgets here

/* Global configuration variables */
char gen;
char neg_pol;
//more variables here

/* Write data to a configuration file. */
void on_Save_Config_Button_clicked()
{
    GtkEntry* save_file = GTK_ENTRY(Save_File_Box_h);
    const gchar* filename = gtk_entry_get_text(save_file);

    FILE* fd = fopen((const char*)filename, "w");

    if(!fd)
    {
        perror("Failed to open file\n");
        exit(EXIT_FAILURE);
    }

    fwrite(&gen, sizeof(gen), 1, fd);
    fwrite(&neg_pol, sizeof(neg_pol), 1, fd);
    //more variables written here

    fclose(fd);

    g_printf("File saved to: %s\n", filename);
}


/* Load data from a stored configuration file */
void on_Load_File_Button_selection_changed()
{
    GtkFileChooser* file = GTK_FILE_CHOOSER(Load_File_Box_h);
    gchar* filename = gtk_file_chooser_get_filename(file);

    FILE* fd = fopen((const char*)filename, "r");

    if(!fd)
    {   
        perror("Failed to open file\n");
        exit(EXIT_FAILURE);
    }   

    fread(&gen, sizeof(gen), 1, fd);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(GEN_CB_h), gen); 

    fread(&neg_pol, sizeof(neg_pol), 1, fd);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(neg_pol_cb), neg_pol);

   /* read more data and update more GUI elements here */
}

/* Callback for negative polarity bit checkbox */
void on_Neg_Pol_CB_toggled()
{   
    GtkToggleButton* neg_pol_cb = GTK_TOGGLE_BUTTON(Neg_Pol_CB_h);

    neg_pol = (char)gtk_toggle_button_get_active(neg_pol_cb);
    printf("Neg pol toggled: %s\n", (neg_pol) ? "ON":"OFF");
}

/* Callback for global enable bit checkbox */
void on_GEN_CB_toggled()
{   
    printf("gen_cb = %p\n", GEN_CB_h); //print before cast for debugging
    GtkToggleButton* gen_cb = GTK_TOGGLE_BUTTON(GEN_CB_h);
    gen = (char)gtk_toggle_button_get_active(gen_cb);
    printf("GEN toggled: %s\n", (gen) ? "ON":"OFF");
}

int main(int argc, char *argv[])
{
    GtkBuilder      *builder;
    GtkWidget       *window;

    gtk_init(&argc, &argv);

    builder = gtk_builder_new();
    gtk_builder_add_from_file (builder, "CFD.glade", NULL);

    window = GTK_WIDGET(gtk_builder_get_object(builder, "window_main"));

    GEN_CB_h = GTK_WIDGET(gtk_builder_get_object(builder, "GEN_CB"));
    Neg_Pol_CB_h = GTK_WIDGET(gtk_builder_get_object(builder, "Neg_Pol_CB"));

    Save_File_Box_h = GTK_WIDGET(gtk_builder_get_object(builder, "Save_File_Name_Box"));
    Load_File_Box_h = GTK_WIDGET(gtk_builder_get_object(builder, "Load_File_Button"));
    Save_File_Button_h = GTK_WIDGET(gtk_builder_get_object(builder, "Save_Config_Button"));

    //create more widgets here 

    gen = 1;
    neg_pol = 0; //positive polarity

    //set more variables here

    gtk_builder_connect_signals(builder, NULL);
    printf("connect returned\n");

    g_object_unref(builder);
    printf("unref returned\n");

    gtk_widget_show(window);
    printf("show returned\n");
    gtk_main();

    return 0;
}

我使用GDB查看导致段错误的原因,并将其报告为:

GtkToggleButton* gen_cb = GTK_TOGGLE_BUTTON(GEN_CB_h);

我还包含了一条printf语句,以检查加载之间的指针是否发生了任何变化,并发现执行此行后正在修改指针值:

Thread 1 "cfd_gui" received signal SIGSEGV, Segmentation fault.
0x00007ffff7395ea0 in g_type_check_instance_cast () from /usr/lib/libgobject-2.0.so.0

我还是GTK3的新手,所以我可能使用的是错误的东西,但无法弄清楚。这是我的printf调试语句的输出:

gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(GEN_CB_h), gen); 

第一行显示在加载配置数据之前指向GEN_CB_h的指针。然后可以清楚地看到,在加载配置数据后更改了指针值。我的调查表明,这种更改是在设置复选框的状态(如上所示)后发生的。

我需要能够更新许多复选框和组合框的状态,以正确反映文件中的加载状态。现在,在我从文件加载数据之前,GUI可以完全正常工作。感谢您的帮助和见解。

编辑:

我应该注意,我包括了Neg_Pol_CB回调,因为此函数在加载配置数据后不会不会导致段错误,而GEN_CB回调会。

1 个答案:

答案 0 :(得分:0)

我解决了。原来我在笔记本电脑上编辑/构建的代码与github上的代码已经过时了(github代码就是我在此处发布的代码)。我以为我拉了,但显然没有。我在编写/读取错误的数据元素大小到文件的一行代码:

fwrite(&gen, sizeof(&gen), 11, fd);
...
fread(&gen, sizeof(&gen), 11, fd);

两个错误,我不小心读/写sizeof(&gen)而不是sizeof(gen),而且我也读/写了11个数据元素,而不是一个。这显然使我覆盖了其他一些指针。我将更新所有回调以匹配签名,但现在一切似乎都可以正常工作。