繁体   English   中英

在将arg作为arg传递给G_CALLBACK时获取GLib警告

[英]Getting GLib warning on passing struct as arg to G_CALLBACK

我试图将指向struct的指针作为回调函数的参数传递,但出现此错误

(gtk:11156): GLib-GObject-WARNING **: 22:34:21.308: invalid cast from 'GtkEntry' to 'GtkApplication'

(gtk:11156): Gtk-CRITICAL **: 22:34:21.308: gtk_application_window_new: assertion 'GTK_IS_APPLICATION (application)' failed

执行此代码时

Appnfile *argptr = (Appnfile*)data;
GtkWidget *window2 = gtk_application_window_new(GTK_APPLICATION(argptr->app1));  //this line has the error

回调函数的原型是

static void second_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);

struct的定义是

typedef struct {
    GApplication *app1;
    GtkEntryBuffer *buff;
} Appnfile;

链接到程序在这里

当我将应用程序作为数据传递给g_signal_connect_swapped函数时,代码工作正常。 但是在传递与struct元素相同的变量时,我得到了这个警告。

亚历山大·德米特里耶夫(Alexander Dmitriev)正确。 您正在尝试在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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM