天天看點

什麼是回調函數

 其實,回調函數大多隻是自己定義一個名字而已,函數體大多是系統定義好的,它有一個結構,一般一個代回調函數的的函數都有一個參數是接你的回調名的,它把一些值傳進回調函數(函數體包括參數是它預定好的,不能自己寫,除非全部函數都是你寫的),然後回調函數接受值,相應操作後将值傳回到原函數體(它的父親函數),最終讓原函數傳回一個值

我們經常在C++設計時通過使用回調函數可以使有些應用(如定時器事件回調處理、用回調函數記錄某操作進度等)變得非常友善和符合邏輯,那麼它的内在機制如何呢,怎麼定義呢?它和其它函數(比如鈎子函數)有何不同呢?這裡結合自己的使用經曆做一個簡單的介紹。

使用回調函數實際上就是在調用某個函數(通常是API函數)時,将自己的一個函數(這個函數為回調函數)的位址作為參數傳遞給那個函數。而那個函數在需要的時候,利用傳遞的位址調用回調函數,這時你可以利用這個機會在回調函數中處理消息或完成一定的操作。至于如何定義回調函數,跟具體使用的API函數有關,一般在幫助中有說明回調函數的參數和傳回值等。C++中一般要求在回調函數前加CALLBACK(相當于FAR PASCAL),這主要是說明該函數的調用方式。

至于鈎子函數,隻是回調函數的一個特例。習慣上把與SetWindowsHookEx函數一起使用的回調函數稱為鈎子函數。也有人把利用VirtualQueryEx安裝的函數稱為鈎子函數,不過這種叫法不太流行。

也可以這樣,更容易了解:回調函數就好像是一個中斷處理函數,系統在符合你設定的條件時自動調用。為此,你需要做三件事:

1.聲明;

2.定義;

3.設定觸發條件,就是在你的函數中把你的回調函數名稱轉化為位址作為一個參數,以便于系統調用。

聲明和定義時應注意:回調函數由系統調用,是以可以認為它屬于WINDOWS系統,不要把它當作你的某個類的成員函數

回調函數是一個程式員不能顯式調用的函數;通過将回調函數的位址傳給調用者進而實作調用。回調函數使用是必要的,在我們想通過一個統一接口實作不同的内容,這時用回掉函數非常合适。比如,我們為幾個不同的裝置分别寫了不同的顯示函數:void TVshow(); void ComputerShow(); void NoteBookShow()...等等。這是我們想用一個統一的顯示函數,我們這時就可以用回掉函數了。void show(void (*ptr)()); 使用時根據所傳入的參數不同而調用不同的回調函數。

       不同的程式設計語言可能有不同的文法,下面舉一個c語言中回調函數的例子,其中一個回調函數不帶參數,另一個回調函數帶參數。

       例子1:

什麼是回調函數

// Test.c

什麼是回調函數
什麼是回調函數

#include  < stdlib.h >

什麼是回調函數

#include  < stdio.h >

什麼是回調函數
什麼是回調函數

int  Test1()

什麼是回調函數
什麼是回調函數

... {

什麼是回調函數

   int i;

什麼是回調函數

   for (i=0; i<30; i++)

什麼是回調函數
什麼是回調函數

   ...{

什麼是回調函數

     printf("The %d th charactor is: %c ", i, (char)('a' + i%26));

什麼是回調函數
什麼是回調函數

   }

什麼是回調函數

   return 0;

什麼是回調函數

}

什麼是回調函數

int  Test2( int  num)

什麼是回調函數
什麼是回調函數

... {

什麼是回調函數

   int i;

什麼是回調函數

   for (i=0; i<num; i++)

什麼是回調函數
什麼是回調函數

   ...{

什麼是回調函數

    printf("The %d th charactor is: %c ", i, (char)('a' + i%26));

什麼是回調函數
什麼是回調函數

   }

什麼是回調函數

   return 0;

什麼是回調函數

}

什麼是回調函數
什麼是回調函數

void  Caller1( void  ( * ptr)())        // 指向函數的指針作函數參數

什麼是回調函數
什麼是回調函數

... {

什麼是回調函數

   (*ptr)();

什麼是回調函數

}

什麼是回調函數

void  Caller2( int  n,  int  ( * ptr)()) // 指向函數的指針作函數參數,這裡第一個參數是為指向函數的指針服務的,

什麼是回調函數

                                                   // 不能寫成void Caller2(int (*ptr)(int n)),這樣的定義文法錯誤。

什麼是回調函數
什麼是回調函數

... {

什麼是回調函數

   (*ptr)(n);

什麼是回調函數

   return;

什麼是回調函數

}

什麼是回調函數

int  main()

什麼是回調函數
什麼是回調函數

... {

什麼是回調函數
什麼是回調函數

   printf("************************ ");

什麼是回調函數

   Caller1(Test1); //相當于調用Test2();

什麼是回調函數

   printf("&&&&&&************************ ");

什麼是回調函數

   Caller2(30, Test2); //相當于調用Test2(30);

什麼是回調函數

   return 0;

什麼是回調函數

}

什麼是回調函數
什麼是回調函數

       以上通過将回調函數的位址傳給調用者進而實作調用,但是需要注意的是帶參回調函數的用法。要實作回調,必須首先定義函數指針。函數指針的定義這裡稍微提一下。比如:

     int (*ptr)(); 這裡ptr是一個函數指針,其中(*ptr)的括号不能省略,因為括号的優先級高于星号,那樣就成了一個傳回類型為整型的函數聲明了。