C/C++回調函數簡要介紹
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.
/*** Copyright (c) 2014 liujun&&baidu. inc All Rights Reserved * **// @filename: pub.h @version: 1.0 @date : 2014/01/28 14時44分05秒 @author: liujun (liujun0923@zju.edu.cn) @breif: */
ifndef PUB_INC
define PUB_INC
include<stdio.h>
//定義一個回調函數,返回為int, 參數為int,int typedef int(*myfoo)(int, int);
endif / ----- #ifndef PUB_INC ----- /</pre>
3.2、callback模塊
頭文件callback.h: 主要定義了一個結構體,包括a,b,回調函數foo。同時有一個執行函數process.
/*** Copyright (c) 2014 liujun&&baidu. inc All Rights Reserved * **// @filename: callback.h @version: 1.0 @date : 2014/01/28 14時46分31秒 @author: liujun (liujun0923@zju.edu.cn) @breif: */
ifndef CALLBACK_INC
define CALLBACK_INC
include "pub.h"
typedef struct _foo_struct_t{ int a; int b; myfoo foo; }foo_struct_t;
int process(foo_struct_t* data);
endif / ----- #ifndef CALLBACK_INC ----- /</pre>
執行函數callback.c: 如果a=100,那么返回10000,否則使用回調函數來執行/*** Copyright (c) 2014 liujun&&baidu. inc All Rights Reserved * **// @filename: callback.c @version: 1.0 @date : 2014/01/28 14時48分26秒 @author: liujun (liujun0923@zju.edu.cn) @breif: */
include "callback.h"
int process(foo_struct_t* data) { int res; //這里你可以做很多事情。
//這里你可以用主函數傳來的函數指針來進行回調 if( data->a == 100) { res = 10000; } else { res = data->foo(data->a, data->b); } //你還是可以做很多事情 return res;
}</pre>
3.3、main模塊
main.c: 從命令行接受參數a,b, 然后將a,b以及myfun函數地址一起參入模塊callback。
/*** Copyright (c) 2014 liujun&&baidu. inc All Rights Reserved * **// @filename: main.c @version: 1.0 @date : 2014/01/28 14時52分48秒 @author: liujun (liujun0923@zju.edu.cn) @breif: */
include "pub.h"
include "callback.h"
include <stdlib.h>
int myfun(int a, int b) { return a+b; }
int main(int argc, char* argv) { foo_struct_t data = (foo_struct_t*)malloc(sizeof(foo_struct_t)); data->a = atoi(argv[1]); data->b = atoi(argv[2]); data->foo = myfun; int res = process(data); printf("after callback is %d\n", res); return 0; }</pre>
3.4、Makefile
先生存libcallback,然后生成可執行文件。
main: main.c libcallback gcc -g main.c -I. -L. -lcallback -o mainlibcallback:callback.h callback.c pub.h gcc -g -c callback.h callback.c pub.h ar -r libcallback.a callback.o
clean: rm .gch rm .o rm *.a rm main</pre>
3.5、執行結果
liujun@ubuntu:~/test/callback$ ./main 100 200 after callback is 10000 liujun@ubuntu:~/test/callback$ ./main 50 200 after callback is 250可以看到達到我們預期效果。
來自:http://my.oschina.net/jungleliu0923/blog/198151