C/C++回調函數簡要介紹

jopen 10年前發布 | 14K 次閱讀 C/C++開發 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 main

libcallback: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

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!