I've been trying to figure out how to implement a hooks system in C. Can anyone give me some pointers or examples?
53 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.
3You 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); }