0

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

4

3 回答 3

1

代码编译是因为打招呼就像提到一个 int 值。例如:

hello; // this just writes the function pointer with a ; so it works
12345; // this is similar to the above and will compile

我假设回调是使用前面提到的宏或连接函数中的其他方式传递参数的。

于 2013-03-13T22:40:55.610 回答
1

您正在做的是通过将指向函数的指针传递给 GLib 来将函数附加到信号。这样做的重点是在触发信号时调用该函数。在这种情况下,即每当按下 GTK 按钮时。基本上,这会将用户操作(按下按钮)链接到您的函数,但这样做的方式是实现 GTK 按钮的代码永远不必知道您的函数。

该宏G_CALLBACK将函数指针转换为类型GCallback,该类型定义为:

typedef void (*GCallback)(void);

正如文档所解释的:

用于结构定义和函数签名中的回调函数的类型。这并不意味着所有回调函数都必须不带参数并返回 void。回调函数所需的签名由使用的上下文确定(例如,它连接到的信号)。使用 G_CALLBACK() 将回调函数转换为 GCallback。

GLib 这样做的原因是为了使回调类型统一(并记录您对宏所做的操作)。GLib 允许使用不同数量参数的回调,但提供了一个通用的、一致的接口来将这些回调附加到信号上。在内部,GLib 使用正确数量的参数分派函数。

要了解有关函数指针的更多信息,请参阅这个 SO 问题:函数指针的意义是什么?

于 2013-03-13T22:48:18.190 回答
0

我怀疑 G_CALLBACK 是一个宏。(宏在编译之前由预处理器扩展,所以看起来无效的 C 可能使用了很多宏。)你应该看看这个宏扩展成什么。它将帮助您弄清楚代码在做什么。

顺便说一句,如果您将函数指针(通过获取函数的地址。例如&hello)传递给另一个函数并且您想在该函数中调用它,您可以这样做(*function)(arg,arg2)

于 2013-03-13T22:29:10.057 回答