我从此链接中获取了代码Hello World In GTK。它使用了许多回调函数,但每个回调函数都说
static void hello( GtkWidget *widget,gpointer data )
当它将它用作回调时,它会
g_signal_connect (button, "clicked",G_CALLBACK (hello), NULL);
但是在这里,它没有向hello()函数传递任何参数。如果我试图在正常的功能中这样做,即
#include <stdio.h>
int hello(int a) {
printf("hello");
}
void main() {
int j=10;
hello;
}
它没有给我任何错误,也没有输出。
Q1。如何回调函数忽略参数?
Q2。如何进行函数回调?即在我的第二个hello
示例中,函数hello是否会回调?
答案 0 :(得分:1)
代码编译因为说你好就像提到一个int值。例如:
hello; // this just writes the function pointer with a ; so it works
12345; // this is similar to the above and will compile
我假设回调是使用前面提到的宏或在connect函数中以其他方式传递的参数。
答案 1 :(得分:1)
您正在做的是通过将pointer to the function传递给GLib来将函数附加到信号。这一点是在触发信号时调用该函数。在这种情况下,即按下GTK按钮。基本上,这会将用户操作(按下按钮)链接到您的函数,但这样做的方式是实现GTK按钮的代码永远不必了解您的函数。
宏G_CALLBACK
会转换一个函数指针,指向GCallback
类型,该类型已定义:
typedef void (*GCallback)(void);
正如文档所述:
结构定义和函数签名中用于回调函数的类型。这并不意味着所有回调函数都必须不带参数并返回void。回调函数的所需签名由使用的上下文(例如,它所连接的信号)确定。使用G_CALLBACK()将回调函数强制转换为GCallback。
GLib执行此操作的原因是使回调类型统一(并记录您正在使用宏执行的操作)。 GLib允许回调采用不同数量的参数,但提供了一个通用,一致的接口,用于将这些回调附加到信号。在内部,GLib使用正确数量的参数调度函数。
要了解有关函数指针的更多信息,请参阅此问题:What is the point of function pointers?
答案 2 :(得分:0)
我怀疑G_CALLBACK是一个宏。 (宏在编译之前由预处理器扩展,所以看起来像无效的C可能使用了很多宏。)你应该看看这个宏扩展到什么。它将帮助您弄清楚代码正在做什么。
顺便说一下,如果你传递一个函数指针(通过获取一个函数的地址,例如&hello
)到另一个函数,并且你想在该函数中调用它,你可以这样做{{{ 1}}