1. 何為回調(callback)
所謂回調,就是客戶程式C調用服務程式S中的某個函數A,然後S又在某個時候反過來調用C中的某個函數B,對於C來說,這個B便叫做回呼函數。例如Win32下的視窗過程函數就是一個典型的回呼函數。
一般說來,C不會自己調用B,C提供B的目的就是讓S來調用它,而且是C不得不提供。由於S並不知道C提供的B叫甚名誰,所以S會約定B的介面規範(函數原型),然後由C提前通過S的一個函數R告訴S自己將要使用B函數,這個過程稱為回呼函數的註冊,R稱為註冊函數。
下面舉個通俗的例子:
某天,我打電話向你請教問題,當然是個難題,:),你一時想不出解決方案,我又不能拿著電話在那裡傻等,於是我們約定:等你想出辦法後打手機通知我,這樣,我就掛掉電話辦其它事情去了。過了XX分鐘,My Phone響了,你興高采烈的說問題已經搞定,應該如此這般處理。故事到此結束。
這個例子說明了“非同步+回調”的編程模式。其中,你後來打手機告訴我結果便是一個“回調”過程;My Phone號碼必須在以前告訴你,這便是註冊回呼函數;My Phone號碼應該有效並且手機能夠接收到你的呼叫,這是回呼函數必須符合介面規範。
2. 什麼情況下使用回調
如果你是SDK的使用者,一旦別人制定了回調機制,那麼你被迫得使用回呼函數,因此這個問題只對SDK設計者有意義。
從引入的目的看,回調大致分為三種:
1) SDK有訊息需要通知應用程式,比如定時器被觸發;
2) SDK的執行需要應用程式的參與,比如SDK需要你提供一種排序演算法;
3) SDK的操作比較費時,但又不能讓應用程式阻塞在那裡,於是採用非同步方式,讓調用函數及時返回,SDK另起線程在後台執行操作,待操作完成後再將結果通知應用程式。
經上面這樣一總結,你也許會恍然大悟:原來“回調機制”無處不在啊!
是的,不光是Win32 API編程中你會用到,也不光是其它SDK編程中會用到,平時我們自己編寫程式時也可能用到回調機制,這時,我們既是回調的設計者又是回調的使用者。