鉤子函數概念及其使用案例

鉤子函數聽起來很抽象,其實只要我們瞭解了回調函數,就好理解了,其實鉤子函數就是回調函數的特殊用法,

利用函數指針進行不同函數的調用,實現不同功能。

首先我們對函數指針的用法進行說明,例如,定義函數指針

 int (* g_pFun) (int x, int y);

有兩個函數:

/*返回兩個參數中的最大值、最小值*/

int Max(int x, int y){ }

int Min(int x, int y){ }

int main(int argc, char* argv[])

{

    int r;

/*我們讓函數指針先後指向不同的函數*/   

int a = 10;

    int b = 15;

    g_pFun = Max;//函數指針的調用

    r= g_pFun(a, b); /*相當於執行函數Max*/

    printf("%d\n", r);

    g_pFun = Min;

    r= g_pFun(a, b); /*相當於執行函數Min*/

    printf("%d\n", r);

    return 0;

}

分別輸出:15、10

這樣,同樣調用g_fun ,兩次卻完成不同的功能,神奇吧?這就是函數指針的妙用。

MaxMin函數就是鉤子函數了,把函數指針g_pFun指向函數MaxMin的過程,就是“掛鉤子”的過程,把鉤子函數“掛”到函數指針上,很形象。

有人可能有疑問,那麼這裏爲什麼不直接調用MaxMin函數呢?

這是因爲,我們在寫main函數的時候,可能還不知道它會完成什麼功能,這時候留下函數指針作爲接口,可以掛上不同的函數完成不同的功能,究竟執行什麼功能由鉤子函數的編寫者完成。

那我們平時怎麼用的呢?在我們的代碼中,常常把掛鉤子的過程叫做註冊,會提供一個註冊函數,讓使用者把自己編寫的鉤子函數掛在已經聲明的函數指針上,這個註冊函數的參數就是我們的函數指針了,比如,我們可以給剛纔的函數指針提供一個註冊函數:

int RegFun( int (* pFun)(int x, int y) ) /*註冊函數的參數是函數指針*/

{

g_pFun = pFun;

return 0;

}

調用RegFun(Max)RegFun(Min),就可以把鉤子函數掛上去了。

注意:爲了便於使用,函數指針往往被聲明爲全局變量,這也是剛纔把函數指針的名字命名爲g_pFun的原因。

下面我們來進行一下實戰演習,比如,平臺部分要執行某一個操作,但是具體的操作還不確定,我們完成這樣的代碼:

int (* g_pFun) (int x, int y);  /*函數指針*/

int Plat()

{

     int r;

     int a = 10;

     int b = 15;

     r= g_pFun(a, b); /*這裏要做一個操作,但是具體的操作還不確定*/

     printf("%d\n", r);

     return 0;

}

另外,平臺部分再提供一個註冊函數:

int RegFun(int (* pFun)(int x, int y))

{

       g_pFun = pFun;

       return 0;

}

 

應用模塊完成具體的函數的功能:

int Max(int x, int y)

{

    if(x>y)

        return x;

    else

        return y;

}

int Min(int x, int y)

{

    if(x<y)

       return x;

    else

       return y;

}

因爲應用模塊無法修改平臺的代碼,只能調用平臺提供的註冊函數:

如果應用模塊註冊:

 RegFun(Max);

則運行 main 函數時,輸出:15

如果應用模塊註冊:

RegFun(Min)

運行 main 函數時,輸出:10

這樣,平臺部分無需修改任何代碼,只是應用模塊註冊了不同的鉤子函數,就能夠完成不同的功能,這就是鉤子函數的妙用。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章