我正在尝试使用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回调会。
答案 0 :(得分:0)
我解决了。原来我在笔记本电脑上编辑/构建的代码与github上的代码已经过时了(github代码就是我在此处发布的代码)。我以为我拉了,但显然没有。我在编写/读取错误的数据元素大小到文件的一行代码:
fwrite(&gen, sizeof(&gen), 11, fd);
...
fread(&gen, sizeof(&gen), 11, fd);
两个错误,我不小心读/写sizeof(&gen)
而不是sizeof(gen)
,而且我也读/写了11个数据元素,而不是一个。这显然使我覆盖了其他一些指针。我将更新所有回调以匹配签名,但现在一切似乎都可以正常工作。