何时知道函数是否是回调?

时间:2013-03-13 22:26:36

标签: c callback

我从此链接中获取了代码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是否会回调?

3 个答案:

答案 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}}