回調函數及其使用
1 回呼函數的概述
回呼函數是這樣一種機制:呼叫者在初始化一個物件(這裡的物件是泛指,包括OOP中的物件、全域函數等)時,將一些參數傳遞給對象,同時將一個呼叫者可以存取的函數地址傳遞給該對象。這個函數就是呼叫者和被呼叫者之間的一種通知約定,當約定的事件發生時,被呼叫者(一般會包含一個工作執行緒)就會依照回呼函數位址呼叫函數。
這種方式,呼叫者在一個線程,被呼叫者在另一個線程。訊息: 訊息也可以看作是某種形式的回調,因為訊息也是在初始化時由呼叫者向被呼叫者傳遞一個句柄和一個訊息編號,在約定的事件發生時被呼叫者傳送訊息給呼叫者。
這種方式,呼叫者在主執行緒中,被呼叫者在主執行緒或工作執行緒中。 Delphi事件模型:
在Delphi的VCL中有很多視覺化元件都是使用事件模型,例如TForm的OnCreate事件,原則是:在設計時指定事件函數,在執行時間事件觸發,則會呼叫設計時指定的事件函數。 在機制上,Delphi事件模型與回調是一樣的。但具體形式有些區別,純的回呼函數是全域函數的形式,而Delphi事件是物件方法的形式,即可以定義如下回呼函數類型type TCallBackFunc = PRocedure (pData: Pointer) of object;
2 回呼函數的使用說明
回調函數主要在兩個場合使用,第一個是某些windows的API要求以回調函數作為其參數位址,另一種是使用者在某種特定的場合定義的某個函數需要使用回呼函數作為其參數地址,對於使用者的定義的函數來說,一般是當呼叫動態連接庫中的函數時使用。對於使用一個回呼函數主要有以下幾個步驟:1、 定義一個回呼函數類型,跟一般的函數過程的定義並沒有什麼區別,但其定義必鬚根據需要滿足回調函數的函數要求,唯一的區別在於在函數或過程的定義後面必須宣告其為windows標準呼叫;例: typeTHDFunction= function(I:integer;s:string):integer; stdcall;對於過程的宣告:type THDProcedure=procedure(s:string); stdcall;2、 然後根據此原形定義一個對應的函數或過程,對於這個函數或過程來說名字沒有什麼要求,對函數其參數的類型和返回值的類型必須和定義的回呼函數類型完全一致,對於過程來說,只需要其參數類型一樣就可以了。例:根據上面的函數和過程的原形定義一個對應的函數和一個對應的過程。函數原形定義:Function HdFunExample(k:integer,sExam:string):integer; stdcall;過程定義:procedure HdProExample(sExam:string);stdcall;3、 在程式中實作此回呼函數或著過程;Function HdFunExample(k :integer,sExam:string):integer; stdcall;BeginEnd;procedure HdProExample(sExam:string);stdcall;beginend; 4、 呼叫過程;回呼函數一般作為系統的某個函數的入口位址;根據呼叫函數的原形:假設有下列呼叫函數:function DyHdFunExample(HdFun:THDFunction;I: integer):boolean;註:在呼叫函數中透過對函數指標的處理可以直接呼叫回呼函數(即呼叫函數中的那個是回呼函數類型的參數,直接操作它),使回調函數履行一定的操作。即在呼叫函數中實作回調函數的功能。呼叫:varI:integer;beginI:=DyHdFunExample(@HdFunExample,i);//…….End;
3 舉例說明
範例程式在H:/ 回呼函數範例/ 目錄下面。回呼函數的使用主要在於windows原有的API函數,但對於使用者的自訂的呼叫函數一般在於動態連線庫中。常規的同一個工程下面一般不需要使用回調函數。 (個人認為).。