c - 将 struct 作为 arg 传递给 G_CALLBACK 时收到 GLib 警告

标签 c gtk gtk3

我试图将结构体指针作为参数传递给回调函数,但出现此错误

(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 存活足够长的时间:

  • 在堆上分配它(使用 mallocg_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/

相关文章:

c - ANSI C 无回声键盘输入

python - 如何避免Python中Gtk.Dialog关闭?

c++ - GTK 应用程序 : How do I create a working indicator with Qt/C++?

python - 如何更改 GTK 小部件(如堆栈)的属性?

python - 如何为 GTK 分隔符创建垂直线性渐变

c - 基础问题 : Best Practices concerning Posix Threads and Dynamic Memory

有人可以解释一下这个过滤器图吗?

c - 如何使用 Win32 API 将字符串传递给 DLL?

linux - 当用户按下可编辑的 UI 组件时在 Linux 中自动启动键盘

linux - 值错误 : Namespace Gtk not available