open source 软件 尤其是 做为 server的源码中,会经常看到很多带callback字眼的函数。
随便在本人放开源软件的opensource目录中查找callback关键字:
[zhang@localhost opensource]$ find .-wholename "*.c" | xargs grep -n --color=auto callback
相关的打印真是不计其数。
什么是callback函数?
callback函数其实是这些C语言编写的服务器中一种模仿C++封装编程技术(本人的说法,不是很准确)。C++中对象封装的技术优点很多,其中重要的一点是,将对象的描述、属性参数 和 对象的相关操作方法(即函数)放在一个类/结构体中。
callback函数的好处:
在传递参数时,仅仅将该对象传给函数,可以减少函数参数的个数,针对不同的功能需求,函数可以针对不通的参数处理处理,忽略不关心的参数(当然函数里面有很多case、 if-else if-else的判断)增加了代码的可重用性。
当增加了新的参数时,将其定义为类/结果体一成员,这样相关函数需要该参数就直接通过其对象获取,原来的函数声明无需改变,增加了代码的可扩展性。
这种封装的特点并不是像C++这种面向对象语言的专利,在linux内核中就大量使用了这种技术,比如驱动、协议栈中。这里只说C语言编程中的callback,就是结构体中定义的函数指针啦。
callback函数示例:
众多的开源项目中,主要是以下面伪代码的方式应用的
struct foo_t
{
type data1;
type date2;
...
func* func1;
func* func2;
...
}
初始化 callback
(也可作为全局变量,如 定义全局struct foo_tfoo[MAX_SIZE])
initFooStruct(struct foo_t * foo, int iSize )
{
for(i=0, i < iSize; i++)
{
foo[i].data1=d1
foo[i].data2=d2
...
foo[i].func1=function1;
foo[i].func2=function2;
...
}
}
调用callback
FooHandle( struct foo_t foo, var1, ...)
{
switch( www )
case yyy:
struct foo_t *p = &foo;
p->func1(nnn, mmm, ...)
break;
case ddd:
struct foo_t *p = &foo;
p->func1(aaa, bbb, ... )
break;
or
if()
...
else if()
...
else if
...
else
...
}
//TODO