GTK将结构传递给C中的回调函数 [英] GTK passing structure to callback function in 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屋!