2016-10-27 64 views
0

我想編寫一個鉤子函數,當我的程序調用一個函數來收集一些關於函數參數的統計信息時,就會調用它。例如:如何在C中編寫函數的通用鉤子?

void hook(function f, ...){ 
    //some statistics here 
    f(...); 
} 
int main(){ 
    foo(1, 2); 
} 

因此而不是直接調用foo,它會調用掛鉤,而不是與foo作爲第一個參數和1, 2作爲額外的參數。

在C中有類似的東西嗎?我可以用其他方式在C中達到這個目標嗎?

+0

在c中你需要有一個函數指針和一個省略號簽名。 –

+0

@πάνταῥεῖ我寫的代碼更多的是僞代碼,而不是真正的代碼。我只想知道這在C中是否可行。 – afsafzal

+2

使用GCC,你可以用'-finstrument-functions'標誌來測試你的代碼。但是,生成的函數不會收到函數的參數列表。另一種選擇是使用預處理器宏,儘管您需要向foo函數明確添加代碼。 –

回答

-1

也許這是你在找什麼?

typedef enum FunctionPointerType_E 
    { 
    FPT_Int_IntInt = 1 
    } FunctionPointerTypes_T 

int foo(
     int a, 
     int b 
    ) 
    { 
    return(a+b); 
    } 

void hook(
     FunctionPointerTypes_T fpt, 
     void (*function)(void), 
     ... 
    ) 
    { 
    int rCode; 
    int (*fp_Int_IntInt)(int, int); 

    switch(fpt) 
    { 
    case FPT_Int_IntInt: 
     fp_Int_IntInt = (int(*)(int, int))function; 
     rCode=(*fp_Int_IntInt)(1,2); 
    ... 
    } 

    return; 
    } 

void CallFooByRefrence(void) 
    { 
    hook(FPT_Int_IntInt, (void(*)(void))foo, ...); 
    return; 
    } 
+0

我需要一個可以在這個程序中的所有函數上工作的鉤子,而不僅僅是一個特定的鉤子。所以我需要一些我不需要指定函數簽名的地方。 – afsafzal

+0

有多種方式可以做到這一點;但通常必須指出返回類型和參數類型以便通過引用來調用它。 (更新答案以反映解決方案) –

0

宏可以(AB)使用一個簡單的方式來實現這一目標:

void foo(int , int); 

void Hook(int a , int b) 
{ 
    //do whatever 
    foo(a , b); 
} 

#define foo(a , b) Hook(a , b) 

int main(void) 
{ 
    foo(1 , 2); 
} 

注意,這是容易出錯,需要認真寫作。

+0

我需要一個適用於此程序中所有功能的鉤子,而不僅僅是一個特定的鉤子。 – afsafzal

+0

@afsafzal你將不得不爲每個函數編寫不同的鉤子。這是唯一的方法。 – 2501