GTK将结构传递给C中的回调函数 [英] GTK passing structure to callback function in C

查看:78
本文介绍了GTK将结构传递给C中的回调函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

GTK的新功能,现在正尝试进行事件驱动的编程,并陷入了怪异的境地:将标量项发送到回调函数没有问题,但是随后就向其发送了struct,但仍然收到错误不知道怎么了.

Still new in GTK, now trying to work on event-driven programming and stuck in weird situation: there is no problem to send scalar items to callback function, but then it comes to sending struct to it, still receiving the error with no idea what's wrong.

示例存根"代码为:

#include <gtk/gtk.h>
#include <stdlib.h>

void messageup();
void exiting();

struct data{
    char *message;
    GtkWidget *window;
};


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

  gtk_init (&argc, &argv);

  builder = gtk_builder_new ();
  gtk_builder_add_from_file (builder, "samplemain.ui", NULL);
  window = GTK_WIDGET (gtk_builder_get_object (builder, "applicationwindow1"));
  entryMainValue = GTK_WIDGET (gtk_builder_get_object (builder, "entryMainValue"));
  g_signal_connect (window, "delete_event", G_CALLBACK (exiting), NULL);
  d.message = "message\n";
  d.window = window;
  g_signal_connect (entryMainValue, "activate", G_CALLBACK (messageup), d);
  g_object_unref (G_OBJECT (builder));
  gtk_widget_show (window);                
  gtk_main ();

  return 0;
}

void messageup(GtkWidget *entryMainValue, gpointer user_data){

    struct data *d = (struct data*) user_data;


    g_print("Hello World!\n%s\n", user_data.message);
}

void exiting()
{
    exit(0);
}

现在出现如下错误:

gtkbldprj.c: In function ‘main’:
gtkbldprj.c:29:3: error: incompatible type for argument 4 of ‘g_signal_connect_data’
   g_signal_connect (entryMainValue, "activate", G_CALLBACK (messageup), d);
   ^
In file included from /usr/include/glib-2.0/gobject/gobject.h:28:0,
                 from /usr/include/glib-2.0/gobject/gbinding.h:29,
                 from /usr/include/glib-2.0/glib-object.h:23,
                 from /usr/include/glib-2.0/gio/gioenums.h:28,
                 from /usr/include/glib-2.0/gio/giotypes.h:28,
                 from /usr/include/glib-2.0/gio/gio.h:26,
                 from /usr/include/gtk-3.0/gdk/gdkapplaunchcontext.h:28,
                 from /usr/include/gtk-3.0/gdk/gdk.h:32,
                 from /usr/include/gtk-3.0/gtk/gtk.h:30,
                 from gtkbldprj.c:1:
/usr/include/glib-2.0/gobject/gsignal.h:388:9: note: expected ‘gpointer’ but argument is of type ‘struct data’
 gulong  g_signal_connect_data        (gpointer    instance,
         ^
gtkbldprj.c: In function ‘messageup’:
gtkbldprj.c:42:41: error: request for member ‘message’ in something not a structure or union
  g_print("Hello World!\n%s\n", user_data.message);
                                         ^
gtkbldprj.c:39:15: warning: unused variable ‘d’ [-Wunused-variable]
  struct data *d = (struct data*) user_data;

任何帮助将不胜感激!

推荐答案

这里有几个C错误.GTK允许您在某些函数上传递 gpointer user_data .一个 gpointer 只是一个 void * (即指向某物的指针).如果要传递结构,则需要结构的地址,而不是结构本身.称为按地址传递,而不是按值传递.

There are several C errors here. GTK allows you on some functions to pass a gpointer user_data. A gpointer is just a void * (ie. a pointer to something). If you want to pass a structure, you need the address of the structure, not the structure itself. That is called passing by address, as opposed to passing by value.

所以,而不是:

g_signal_connect (entryMainValue, "activate", G_CALLBACK (messageup), d);

写:

g_signal_connect (entryMainValue, "activate", G_CALLBACK (messageup), &d);

然后,当您在回调中时,收到的 user_data 参数是指向某物的指针.您需要将其转换为指向您的结构的指针.

Then, when you're in the callback, the user_data parameter you receive is a pointer to something. You need to transform it into a pointer to your structure.

所以代替:

void messageup(GtkWidget *entryMainValue, gpointer user_data)
{
    struct data *d = (struct data*) user_data;
    g_print("Hello World!\n%s\n", user_data.message);
}

您需要使用正确类型( d ,而不是 user_data )的指针访问 message 字段,并使用-> 运算符,因为您正在通过指针访问结构:

You need to access the message field using a pointer of the right type (d, not user_data), and use the -> operator as you're accessing the structure through a pointer:

void messageup(GtkWidget *entryMainValue, gpointer user_data)
{
    struct data *d = user_data;
    g_print("Hello World!\n%s\n", d->message);
}

您似乎对指针感到困惑,因此,请看一下这段不错的有关C指针的视频.

You seem confused about pointers, so give a look at this nice video about C pointers.

另一个错误是连接到 delete-event 退出.此事件是在您要捕获用户单击窗口的出口十字或使用Alt-F4退出的事实,并且此时您想要执行某项操作(显示确认弹出窗口,保存一些数据)时.因此,无需在那里连接,将发生破坏(使用 destroy 信号).

Another error is connecting to the delete-event to exit. This event is when you want to catch the fact that the user clicked on the exit cross of the window, or used Alt-F4 to exit, and you want to do something at that moment (show a confirmation popup, save some data). So there's no need to connect there, the destruction will happen (that uses the destroy signal).

因此代替连接到 delete-event 信号,连接到 destroy 信号,并响应该信号,退出GTK +主循环:

So instead of connecting to the delete-event signal, connect to the destroy signal, and in response to this signal, exit the GTK+ main loop:

g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);

这篇关于GTK将结构传递给C中的回调函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆