回调函数
来源:互联网 发布:有关姓氏的软件 编辑:程序博客网 时间:2024/06/05 11:23
1、引子
在C/C++里面有个非常给力的库函数qsort,相信大家都用过。他的函数原型如下:
void qsort(void *base,size_tnmemb,size_tsize, int(*compar)(constvoid*, constvoid*));
使用的时候需要传递需要排序的数组base, 数组数目nmeb, 每个数组大小size,以及我们比较自定义的回调函数:compar.
2、概念
如compar所示,如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。
和回调函数相对,普通函数调用一般为同步调用,即A模块阻塞调用B模块函数,B模块执行完毕之后会讲结果返回给A模块。
回调函数则不同。A模块定义一个回调函数C,将函数指针C传给B模块作为参数。在调用B模块之后,B模块会根据一定的条件触发回调C,进而重新调用模块A的函数。
这样模块B就不用关心回调函数自己的具体实现,这样可以是系统架构更加清晰,可以提高系统的可扩展性。
3、举例
现在我们有个模块叫callback模块。callback模块会接受主函数main传来的a,b,回调函数c.
如果a==100,那么就返回10000,否则就使用我们的回调函数,执行c(a,b),并返回。
具体如下所示:
3.1、通用头文件 pub.h
这里主要定义了一个函数指针。
函数原型为 int myfoo(int, int);
如果有疑问,请自行Google or Baidu.
01
/***************************************************************************
02
*
03
* Copyright (c) 2014 liujun&&baidu. inc All Rights Reserved
04
*
05
**************************************************************************/
06
07
/*
08
* @filename: pub.h
09
* @version: 1.0
10
* @date : 2014/01/28 14时44分05秒
11
* @author: liujun (liujun0923@zju.edu.cn)
12
* @breif:
13
*/
14
15
#ifndef PUB_INC
16
#define PUB_INC
17
18
#include<stdio.h>
19
20
//定义一个回调函数,返回为int, 参数为int,int
21
typedef
int
(*myfoo)(
int
,
int
);
22
23
#endif /* ----- #ifndef PUB_INC ----- */
3.2、callback模块
头文件callback.h: 主要定义了一个结构体,包括a,b,回调函数foo。同时有一个执行函数process.
01
/***************************************************************************
02
*
03
* Copyright (c) 2014 liujun&&baidu. inc All Rights Reserved
04
*
05
**************************************************************************/
06
07
/*
08
* @filename: callback.h
09
* @version: 1.0
10
* @date : 2014/01/28 14时46分31秒
11
* @author: liujun (liujun0923@zju.edu.cn)
12
* @breif:
13
*/
14
15
16
#ifndef CALLBACK_INC
17
#define CALLBACK_INC
18
19
#include "pub.h"
20
21
typedef
struct
_foo_struct_t{
22
int
a;
23
int
b;
24
myfoo foo;
25
}foo_struct_t;
26
27
int
process(foo_struct_t* data);
28
29
#endif /* ----- #ifndef CALLBACK_INC ----- */
执行函数callback.c: 如果a=100,那么返回10000,否则使用回调函数来执行
01
/***************************************************************************
02
*
03
* Copyright (c) 2014 liujun&&baidu. inc All Rights Reserved
04
*
05
**************************************************************************/
06
07
/*
08
* @filename: callback.c
09
* @version: 1.0
10
* @date : 2014/01/28 14时48分26秒
11
* @author: liujun (liujun0923@zju.edu.cn)
12
* @breif:
13
*/
14
15
#include "callback.h"
16
17
int
process(foo_struct_t* data)
18
{
19
int
res;
20
//这里你可以做很多事情。
21
22
//这里你可以用主函数传来的函数指针来进行回调
23
if
( data->a == 100)
24
{
25
res = 10000;
26
}
27
else
28
{
29
res = data->foo(data->a, data->b);
30
}
31
//你还是可以做很多事情
32
return
res;
33
}
3.3、main模块
main.c: 从命令行接受参数a,b, 然后将a,b以及myfun函数地址一起参入模块callback。
01
/***************************************************************************
02
*
03
* Copyright (c) 2014 liujun&&baidu. inc All Rights Reserved
04
*
05
**************************************************************************/
06
07
/*
08
* @filename: main.c
09
* @version: 1.0
10
* @date : 2014/01/28 14时52分48秒
11
* @author: liujun (liujun0923@zju.edu.cn)
12
* @breif:
13
*/
14
15
#include "pub.h"
16
#include "callback.h"
17
#include <stdlib.h>
18
19
int
myfun(
int
a,
int
b)
20
{
21
return
a+b;
22
}
23
24
int
main(
int
argc,
char
** argv)
25
{
26
foo_struct_t* data = (foo_struct_t*)
malloc
(
sizeof
(foo_struct_t));
27
data->a =
atoi
(argv[1]);
28
data->b =
atoi
(argv[2]);
29
data->foo = myfun;
30
int
res = process(data);
31
printf
(
"after callback is %d\n"
, res);
32
free
(data);
33
return
0;
34
}
3.4、Makefile
先生存libcallback,然后生成可执行文件。
main: main.c libcallbackgcc -g main.c -I. -L. -lcallback -o mainlibcallback:callback.h callback.c pub.hgcc -g -c callback.h callback.c pub.har -r libcallback.a callback.oclean:rm *.gchrm *.orm *.arm main
3.5、执行结果
liujun@ubuntu:~/test/callback$ ./main 100 200after callback is 10000liujun@ubuntu:~/test/callback$ ./main 50 200after callback is 250
可以看到达到我们预期效果。
最后给个具体的例子:
https://github.com/jungleliu0923/myserver
客户端C连接例子部分代码如下,其中mys_server_set_callback就是使用回调。
01
int
main()
02
{
03
my_log_init(
"./log"
,
"sample.log"
,
"sample.log.wf"
, 16);
04
server = my_server_create(
"./conf/"
,
"myserver.conf"
,
"sample"
);
05
if
(server == NULL)
06
{
07
cout <<
"create sever fail\n"
;
08
return
-1;
09
}
10
my_server_set_callback(server, my_callback);
11
my_server_run(server);
12
return
0;
13
}
- .NET 回调函数
- 回调函数
- 回调函数
- 回调函数概念
- 回调函数
- 回调函数
- 回调函数
- 回调函数 相关
- delphi 回调函数
- 回调函数
- 回调函数
- 回调函数学习
- 回调函数
- 关于回调函数
- 透析回调函数
- 回调函数
- 什么是回调函数
- 回调函数
- 通过UltraISO来提取U盘启动盘的ISO镜像文件
- 带默认形参的函数(笔记)
- JAVA Excel导入导出POI精致总结[顶赞转]
- 使用java模拟Get与Post请求
- HADOOP 2架构图
- 回调函数
- 黑马程序员-->14_类加载器
- 一个用户自动回复所有的帖子
- 交换a、b不用第三个参数
- PHP面试问题总结
- Android网络请求库——android-async-http使用
- mysql之explain详解
- 字符数组与字符指针
- jQuery父级以及同级元素查找介绍