你到一個商店買東西,恰好你要的東西沒有貨,因而你在店員那裏留下了你的電話,過了幾天店裏有貨了,店員就打了你的電話,而後你接到電話後就到店裏去取了貨。在這個例子裏,你的電話號碼就叫回調函數,你把電話留給店員就叫登記回調函數,店裏後來有貨了叫作觸發了回調關聯的事件,店員給你打電話叫作調用回調函數,你到店裏去取貨叫作響應回調事件。html
在看LWIP時,見到用回調函數,再看某老外公司OPC源代碼時,見到用回調函數。看我國內某些代碼(我公司軟件等)時沒用到。因而,我對回調函數產生了很大的好奇。之前,我寫VC程序時用到過回調函數,可是沒有用C語言來使用。最近,看到國外大量的經典代碼中普遍使用了回調函數(LWIP、某兩個公司的OPC程序等),都是C語言來實現的,而不是VC windows程序中別人實現本身使用的那種。算法
爲了弄明白這種函數的奧妙,首先提出三個問題:編程
1. 回調函數是什麼東西?windows
2. 回調函數怎麼開發,怎麼使用?異步
3. 回調函數的做用,應該在什麼狀況下使用?socket
帶着問題來學習,有目的!呵呵,我的經驗。ide
打開baidu.com、google.cn搜索了好多資料,以下:函數
順便提一下,某君的一個簽名很讓我佩服:1好好活着,由於咱們會死好久。2五千年的文明 兩百年的無奈學習
第一個問題:google
*******************************************************************************
其實回調就是一種利用函數指針進行函數調用的過程.
爲何要用回調呢?好比我要寫一個子模塊給你用, 來接收遠程socket發來的命令.當我接收到命令後, 須要調用你的主模塊的函數, 來進行相應的處理.可是我不知道你要用哪一個函數來處理這個命令, 我也不知道你的主模塊是什麼.cpp或者.h, 或者說, 我根本不用關心你在主模塊裏怎麼處理它, 也不該該關心用什麼函數處理它...... 怎麼辦?
使用回調!
—— lone wolf
使用回調函數實際上就是在調用某個函數(一般是API函數)時,將本身的一個函數(這個函數爲回調函數)的地址做爲參數傳遞給那個函數。而那個函數在須要的時候,利用傳遞的地址調用回調函數,這時你能夠利用這個機會在回調函數中處理消息或完成必定的操做。
—— 某專家
回調函數,就是由你本身寫的。你須要調用另一個函數,而這個函數的其中一個參數,就是你的這個回調函數名。這樣,系統在必要的時候,就會調用你寫的回調函數,這樣你就能夠在回調函數裏完成你要作的事。
—— 綠葉
http://hi.baidu.com/zhuyipeng/blog/item/863fefdb7c736c63d1164eec.html 是一篇比較好的文章。
什麼是回調函數?
回調函數是應用程序提供給Windows系統DLL或其它DLL調用的函數,通常用於截獲消息、獲取系統信息或處理異步事件。應用程序把回調函數的地址指針告訴DLL,而DLL在適當的時候會調用該函數。回調函數必須遵照事先規定好的參數格式和傳遞方式,不然DLL一調用它就會引發程序或系統的崩潰。一般狀況下,回調函數採用標準WindowsAPI的調用方式,即__stdcall,固然,DLL編制者能夠本身定義調用方式,但客戶程序也必須遵照相同的規定。在__stdcall方式下,函數的參數按從右到左的順序壓入堆棧,除了明確指明是指針或引用外,參數都按值傳遞,函數返回以前本身負責把參數從堆棧中彈出。
理解回調函數!
—— jufengfeng
Function Pointers provide the concept of callback functions.
—— newty.de
*******************************************************************************
看了這麼多的資料,我只將每位的定義總結一下就一句話:回調函數就是函數指針的一種用法。
在部分資料上,大量討論了回調函數怎麼被調用,到底被誰調用,還有好多的圖形,我認爲都沒有看到問題的本質。
第二個問題:
*********************************************************************
我實現了一個很簡單的回調函數。
#include <stdio.h>
void printWelcome(int len)
{
printf("歡迎歡迎 -- %d/n", len);
}
void printGoodbye(int len)
{
printf("送客送客 -- %d/n", len);
}
void callback(int times, void (* print)(int))
{
int i;
for (i = 0; i < times; ++i)
{
print(i);
}
printf("/n我不知道你是迎客仍是送客!/n/n");
}
void main(void)
{
callback(10, printWelcome);
callback(10, printGoodbye);
printWelcome(5);
}
*******************************************************************************
上面的代碼沒有被任何系統函數調用,說明那些東西只是撒撒土迷迷路人眼而已。還有面相對象編程時,用class給封裝起來也是掩人耳目,不要被外表所迷惑。
第三個問題:
*********************************************************************
用過STL的人都知道,在STL中衆多算法和程序都用到回調函數,這實現了一種策略。只要任何符合個人標準的函數和計算均可以用我這個公式。你能夠實現各類各樣的回調函數,只要符合個人格式就能用。
就上面的程序來講,你只要函數格式符合cllback第二個參數的格式不論你給別人作飯、鋪牀疊被均可以正常工做。這就是回調的做用,把回調實現留給別人。
這是一個用法。
有一位朋友用分層的概念來解釋了回調機制:callback函數爲B層,main函數和print*函數爲A層,A層調用了B層的回調函數callmeback,而B層的回調函數調用了A層的實現函數print*。說白了B層就是一個接口。