C Hook/Callback System

C Hook/Callback System

I've been trying to figure out how to implement a hooks system in C. Can anyone give me some pointers or examples?

5

3 Answers

Use function pointers:

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);
     }
}

Alternatively, you could create a dispatching service:

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);
    }
}

With the second solution, you have the advantage of multiple listeners for a single callback.

3

You can see the qsort example:

/* 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 need a function pointer that is the callback for sorting.

Im not sure what are u looking for exactly, but ive been developing application using hooks, in QT/C++, so i can give you little example.

First, declare function prototype,like this

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

then, you need to set the hook, in main function, like this:

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

and then you need to define callback function, i can give you code of mine>

//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);

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Sophia Al-Mansoor
Author

Sophia Al-Mansoor

Sophia analyzes international trade, startup ecosystems, retail transformation, and supply chain logistics for modern digital publications.