我试图将结构体指针作为参数传递给回调函数,但出现此错误
(gtk:11156): GLib-GObject-WARNING **: 22:34:21.308: 从“GtkEntry”到“GtkApplication”的转换无效
(gtk:11156): Gtk-CRITICAL **: 22:34:21.308: gtk_application_window_new: 断言“GTK_IS_APPLICATION(应用程序)”失败
执行此代码时
Appnfile *argptr = (Appnfile*)data;
GtkWidget *window2 = gtk_application_window_new(GTK_APPLICATION(argptr->app1)); //this line has the error
回调函数的原型(prototype)为
static void secondary_win(GtkEntry *entry, gpointer data)
;
struct 和 g_signal_connect 行的声明是
Appnfile arg;
arg.app1=app;
arg.buff=buffer;
g_signal_connect(name, "activate",G_CALLBACK(second_win),&arg);
结构体的定义是
typedef struct {
GApplication *app1;
GtkEntryBuffer *buff;
} Appnfile;
该程序的链接是 here
当我将应用程序作为 g_signal_connect_swapped 函数的数据传递时,代码运行良好。但是在将相同的变量作为结构元素传递时,我收到此警告。
最佳答案
亚历山大·德米特里耶夫说得对。您尝试在 Second_win 中使用 arg ,但由于 arg 是在堆栈上分配的结构,因此一旦从该函数返回,它就不复存在了。有两种解决方案可以让 arg
存活足够长的时间:
- 在堆上分配它(使用
malloc
或g_malloc
/g_new
/g_new0
) - 将其分配到函数的堆栈上,仅当不再使用
arg
时才返回
这是使用第二种解决方案的补丁。您可以将其保存在 arg.patch
中,并使用 git am arg.patch
应用它:
From 6c0679485cde31c55c58aa5f54f0a60d4c874d71 Mon Sep 17 00:00:00 2001
From: Luis Menina <liberforce@freeside.fr>
Date: Wed, 27 Feb 2019 10:41:58 +0100
Subject: [PATCH] Create argument list where it will live long enough to be
accessed
Declaring it on the stack inside a callback will make it be destroyed
when you exit the callback. By declaring it in the stack, in the main
you are sure that the structure has the same lifespan as your
application.
---
prog_c/gtk_pr_a.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/prog_c/gtk_pr_a.c b/prog_c/gtk_pr_a.c
index fb3b5a2..d11ba7d 100644
--- a/prog_c/gtk_pr_a.c
+++ b/prog_c/gtk_pr_a.c
@@ -80,6 +80,7 @@ static void first_win(GApplication *app, gpointer data){
GObject *window, *name;
GError *error =NULL;
GtkEntryBuffer *buffer;
+ Appnfile *arg = data;
builder= gtk_builder_new();
if(gtk_builder_add_from_file( builder, "pr1.ui",&error)==0){
@@ -97,10 +98,9 @@ static void first_win(GApplication *app, gpointer data){
gtk_widget_show_all(GTK_WIDGET(window));
g_signal_connect( name, "activate", G_CALLBACK(search_user),buffer);
- Appnfile arg;
- arg.app1=app;
- arg.buff=buffer;
- g_signal_connect(name, "activate",G_CALLBACK(second_win),&arg);
+ arg->app1=app;
+ arg->buff=buffer;
+ g_signal_connect(name, "activate",G_CALLBACK(second_win), arg);
g_signal_connect_swapped( name, "activate", G_CALLBACK(gtk_window_close),window);
g_object_unref(window);
}
@@ -117,7 +117,10 @@ static void first_win(GApplication *app, gpointer data){
int main(int argc, char *argv[]){
GtkApplication *app = gtk_application_new("org.my.app",
G_APPLICATION_FLAGS_NONE);
- g_signal_connect(app, "activate", G_CALLBACK(first_win),NULL);
+ Appnfile arg;
+ memset(&arg, 0, sizeof(arg));
+
+ g_signal_connect(app, "activate", G_CALLBACK(first_win), &arg);
//g_signal_connect(app, "2win",G_CALLBACK(second_win),NULL);
int status =g_application_run(G_APPLICATION(app),argc, argv);
g_object_unref(app);
--
2.17.1
关于c - 将 struct 作为 arg 传递给 G_CALLBACK 时收到 GLib 警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54871484/