【发布时间】:2026-01-03 22:25:01
【问题描述】:
你能转换这种类型的函数指针吗:
void (*one)(int a)
到这种类型之一:
void (*two)(int a, int b)
然后使用已强制转换的附加参数安全地调用指向函数?我曾认为这样的事情是非法的,两种函数类型都必须兼容。 (意思是相同的原型——相同的返回值,相同的参数列表。)但这正是这段 GTK+ 代码正在做的事情(取自here):
g_signal_connect_swapped(G_OBJECT(button), "clicked",
G_CALLBACK(gtk_widget_destroy), G_OBJECT(window));
如果您查看“clicked”信号(或仅查看第一个链接中的其他使用示例),您会看到它的处理程序应该像这样声明:
void user_function(GtkButton *button, gpointer user_data);
当您通过 g_signal_connect_swapped() 注册处理程序时,小部件指针和数据指针参数按顺序交换,因此,声明应如下所示:
void user_function(gpointer user_data, GtkButton *button);
这就是问题所在。注册为回调的 gtk_widget_destroy() 函数原型如下:
void gtk_widget_destroy(GtkWidget *widget);
只接受一个参数。据推测,因为数据指针(一个 GtkWindow)和指向信号小部件的指针(一个 GtkButton)交换了,它接收的唯一参数将是窗口指针,然后传递的按钮指针将被忽略.一些谷歌搜索已经找到了类似的例子,甚至注册了像 gtk_main_quit() 这样根本不带参数的函数。
我认为这违反标准是否正确? GTK+ 开发人员是否找到了一些合法的魔法来让这一切顺利进行?
【问题讨论】: