你能转换一个这种类型的函数指针吗:
void (*one)(int a)
到这种类型之一:
void (*two)(int a, int b)
然后使用附加参数安全地调用指向的函数?我曾认为这样的事情是非法的,两种函数类型必须兼容。 (意思是相同的原型(prototype)——相同的返回值,相同的参数列表。)但这正是这段 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() 函数的原型(prototype)如下:
void gtk_widget_destroy(GtkWidget *widget);
只接受一个参数。据推测,因为数据指针(一个 GtkWindow)和指向信号部件的指针(一个 GtkButton)被交换了,它接收的唯一参数将是窗口指针,而之后传递的按钮指针将被默默地忽略.一些谷歌搜索已经找到了类似的例子,甚至注册了像 gtk_main_quit() 这样完全不带参数的函数。
我认为这是违反标准的做法是否正确? GTK+ 开发人员是否发现了一些合法的魔法来使这一切正常进行?
最佳答案
C 调用约定要求调用者负责清理堆栈上的参数。因此,如果调用者提供了太多参数,这不是问题。其他参数将被忽略。
所以是的,您可以将一个函数指针转换为另一个具有相同参数的函数指针类型,然后再使用一些参数,然后使用太多参数调用原始函数并且它会起作用。
关于您能否将指向一种类型的函数的指针强制转换为另一种带有额外参数的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2022715/