2012-03-03 4 views
1

나는 C로 훅 시스템을 구현하는 방법을 알아 내려고 노력해 왔습니다. 누군가 포인터 나 예제를 제공 할 수 있습니까?C 훅/콜백 시스템

+3

다음은 포인터입니다 : void * (*) (void *)'. –

+0

dlopen? 플러그인 또는 확장을 지원하는 응용 프로그램 (예 : apache http server, lighttpd 또는 브라우저)을 고려하십시오 (예 : nsapi) – qrtt1

+1

아니요, 포인터가 아닙니다. 이것은 구문상의 쓰레기입니다. – Swiss

답변

2

사용 함수 포인터 :

struct callbacks { 
    void (*somethingHappened)(void *context); 
    bool (*shouldIDoSomething)(void *context); 
}; 

void doSomethingAwesome(void *operationData, struct callbacks callbacks) 
{ 
    // context is the data you pass to the function 
    if (callbacks.shouldIDoSomething(context)) 
    { 
      // do something 
      callbacks.somethingHappened(context); 
    } 
} 

는 다른 방법으로는 파견 서비스를 만들 수 있습니다 : 두 번째 솔루션으로

struct dictionary 
{ 
    char **keys; 
    void **values;   

    int count; 
}; 

struct list 
{ 
    void **values; 

    int count; 
}; 

// functions to add, remove, etc; 

struct dictionary *callbacks = NULL; 
void registerForDispatch(char *key, void (*callback)(void *)) 
{ 
    if (!callbacks) 
    { 
     callbacks = dictionary_create(10); // dictionary with 10 key/value pairs 
    } 

    if (!dictionary_containsKey(callbacks, key)) 
    { 
     struct list *callBacksForKey = list_create(10); // default 10 callbacks, array should be auto-expanding 

     dictionary_setValue(callbacks, key, arr); 
    } 

    struct list *callBacksForKey = dictionary_getValue(callbacks, key); 

    list_addObject(callBacksForKey, callback); 
} 

void unregisterFromDispatch(char *key, void (*callback)(void *)) 
{ 
    struct list *callBacksForKey = dictionary_getValue(callbacks, key); 

    list_removeObject(callback); 
} 

void sendNotification(char *key, void *context) 
{ 
    struct list *callBacksForKey = dictionary_getValue(callbacks, key); 

    for (int i = 0; list->count; i++) 
    { 
     void (*callback)(void *) = list->values[i]; 
     callback(context); 
    } 
} 

, 당신은 하나의 콜백 여러 청취자의 장점이 있습니다.

+0

다소 일반적인 콜백 시스템의 경우, void 포인터가 제공하는 컨텍스트가 매우 유용하다. 그러한 문맥이없는 사람들 (예를 들어,'qsort()')은 문제가 될 수 있습니다. 그러나'qsort()'로 컨텍스트를 필요로하는 모든 사람들은 아닙니다. [''qsort_r()'] (https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/qsort_r.3.html)을 참조하십시오. –

+0

두 번째 해결책은 제가 찾고있는 것입니다. 모듈 형 IRC 데몬을 작성 중이며 후크 시스템을 구현하는 방법을 모르겠습니다. 감사! –

+0

@AaronThomasBlakely 문제가 없으므로 답변을 수락하십시오 (답변 옆에있는 체크 표시를 클릭하십시오). –

0

당신은 qsort가 예를 볼 수 있습니다 http://www.cplusplus.com/reference/clibrary/cstdlib/qsort/

/* qsort example */ 
#include <stdio.h> 
#include <stdlib.h> 

int values[] = { 40, 10, 100, 90, 20, 25 }; 

int compare (const void * a, const void * b) 
{ 
    return (*(int*)a - *(int*)b); 
} 

int main() 
{ 
    int n; 
    qsort (values, 6, sizeof(int), compare); 
    for (n=0; n<6; n++) 
    printf ("%d ",values[n]); 
    return 0; 
} 

qsort가 정렬에 대한 콜백하는 함수 포인터가 필요합니다.

0

정확하게 무엇을 찾고 있는지 모르겠지만 QT/C++에서 후크를 사용하여 응용 프로그램을 개발하고 있으므로 약간의 예를들 수 있습니다.

HHOOK mouseHook; 
HINSTANCE appInstance = GetModuleHandle(NULL); 
mouseHook = SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseProc, appInstance, 0); //set global mouse hook 

을 다음 콜백 함수를 정의해야합니다

첫째,이

LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam); 

처럼, 함수 프로토 타입을 선언,이 같은 주요 기능에 후크를 설정해야 , 내 코드를 제공 할 수 있습니다.>

//Mouse hook callback function. 

LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam){ 


    if (nCode == HC_ACTION) { 

    switch(wParam){ 
    case WM_LBUTTONUP: 
    case WM_RBUTTONUP: 
    case WM_MOUSEWHEEL: 
#ifdef DEBUG 
     w->printText("Scrolling or click"); 
#endif 
     w->save_key("MOUSE"); 
     i++; 
     break; 

    default: break; 
    } 
    } 
    return CallNextHookEx(mouseHook, nCode, wParam, lParam); 

}