钩子函数和回调函数个人理解-C语言

一句话概括:本质上都是对函数指针的调用。callback func是将函数作为参数传入, hook则是通过钩子注册函数操作作为全局变量的钩子指针来选择调用对象。目前我能感知到的区别就是业务隔离:callback的调用需要你知道你要传递什么功能实现到函数内部, 而如果不知道的话就可以用hook注册函数来操作。另外hook可以看作是一种已经内嵌入函数的为可拓展性(可通过注册新函数来达到扩展功能的目的,这也是目前搜到的关于hook概念提及最多的点)。

因为暂时没有接触到相关的业务模型,所以不是很理解具体业务场景下怎么选择。

Function pointer

函数指针的声明

int (*ptrFunc1) ();		// a pointer named ptrFunc1 that points to a function taking no arguments and returning an integer
void (*ptrFunc2)(int); 	// a pointer named ptrFunc2 that points to a function taking one integer arguments and returning an integer

函数指针的简单示例

#include<stdio.h>
int func(int, int);
int main(void)
{
    int result1,result2;
    /* declaring a pointer to a function which takes
       two int arguments and returns an integer as result */
    int (*ptrFunc)(int,int); 
 
    /* assigning ptrFunc to func's address */                     
    ptrFunc=func; 
 
    /* calling func() through **explicit dereference** */
    result1 = (*ptrFunc)(10,20); 
 
    /* calling func() through **implicit dereference** */         
    result2 = ptrFunc(10,20);               
    printf("result1 = %d result2 = %d\n",result1,result2);
    return 0;
}
 
int func(int x, int y)
{
    return x+y;
}

CALLBACK FUNCTION

Defination

In computer programming, a callback is a reference to executable code, or a piece of executable code, that is passed as an argument to other code. This allows a lower-level software layer to call a subroutine (or function) defined in a higher-level layer. 1

Example2

// Define callback type
typedef void (*callback)(int);

// Operating function that invokes callback
int MyFunc(char* str,int num, callback curCallback){
	printf("MyFunc has %s\r\n",str);
	curCallback(num);
	return 0;
}

// Callback function defination
void MyCallback(int arg){
	printf("\tbalabala my_callback %d!\r\n", arg);
}

void MyCallback2(int arg){
	printf("\tOhhhhhh! my_callback %d!\r\n", arg);
}

int main(void){
    callback ptrCallback = MyCallback;
	printf("Oh in main!\r\n");
    MyFunc("ptrCallback",6, ptrCallback);
    MyFunc("MyCallback",666, MyCallback);
    MyFunc("&MyCallback",999, &MyCallback);
    MyFunc("MyCallback2",666, MyCallback2);
    return 0;
}

输出:

Oh in main!
MyFunc has ptrCallback
	balabala my_callback 6!
MyFunc has MyCallback
	balabala my_callback 666!
MyFunc has &MyCallback
	balabala my_callback 999!
MyFunc has MyCallback2
	Ohhhhhh! my_callback 666!

用处

在固定接口形式以后,将调用者与被调用者解耦。调用者不需要关心函数的具体实现。
C语言中常用的两个例子:
void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))
void *bsearch(const void *key, const void *base, size_t nitems, size_t size, int (*compar)(const void *, const void *))
通过将比较函数的具体实现与排序算法解耦,将排序算法的具体实现交给使用者,大大扩展了排序算法的实用性

HOOK FUNCTION

Defination

In computer programming, the term hooking covers a range of techniques used to alter or augment the behaviour of an operating system, applications, or other software components, by intercepting function calls or messages or events passed between software components. Code that handles such intercepted function calls, events or messages is called a hook. 3

Example4

typedef int (*hook)(int,int);
hook g_pFun;	// hook is usually a global variable

int Plat(void) {
    int a = 10;
    int b = 15;
    printf("%d\n", g_pFun(a, b));
    return 0;
}

// registration function
int RegFun(int (*pFun)(int x, int y)) {
    g_pFun = pFun;
    return 0;
}
 
int Max(int x, int y) {
    printf("MAX\r\n");
    return (x > y ? x : y);
}
 
int Min(int x, int y) {
    printf("MIN\r\n");
    return (x < y ? x : y);
}

int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
    RegFun(Min);
    Plat();
    RegFun(Max);
    Plat();
    return NULL;
}

  1. Wikipedia-Callback ↩︎

  2. Function Pointers and Callbacks in C – An Odyssey ↩︎

  3. WikiPedia-Hooking ↩︎

  4. CSDN-c语言钩子函数 ↩︎

  • 38
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
三:程序的设计: I:设置钩子 设置钩子是通过SetWindowsHookEx ()的API函数. 原形: HHOOK SetWindowsHookEx(int idHook,HOOKPROC lpfn,HINSTANCE hMod,DWORD dwThreadId) idhook:装入钩子的类型. lpfn: 钩子进程的入口地址 hMod: 应用程序的事件句柄 dwThreadId: 装入钩子的线程标示 参数: idHook: 这个参数可以是以下值: WH_CALLWNDPROC、WH_CALLWNDPROCRET、WH_CBT、WH_DEBUG、WH_FOREGROUNDIDLE、WH_GETMESSAGE、WH_JOURNALPLAYBACK、WH_JOURNALRECORD、WH_KEYBOARD、 WH_KEYBOARD_LL、WH_MOUSE、WH_MOUSE_LL、WH_MSGFILTER、WH_SHELL、WH_SYSMSGFILTER。 对于这些参数,我不想一一加以解释,因为MSDN中有关于他们的详细注解。我只挑选其中的几个加以中文说明。 WH_KEYBOARD:一旦有键盘敲打消息(键盘的按下、键盘的弹起),在这个消息被放在应用程序的消息队列前,WINDOWS将会调用你的钩子函数钩子函数可以 改变和丢弃键盘敲打消息。 WH_MOUSE:每个鼠标消息在被放在应用程序的消息队列前,WINDOWS将会调用你的钩子函数钩子函数可以改变和丢弃鼠标消息。 WH_GETMESSAGE:每次当你的应用程序调用一个GetMessage()或者一个PeekMessage()为了去从应用程序的消息队列中要求一个消息时,WINDOWS都会调用你的钩子函数。 而钩子函数可以改变和丢弃这个消息。 II:释放钩子 钩子的释放使用的是UnhookWindowsHookEx()函数 原形:BOOL UnhookWindowsHookEx( HHOOK hhk ) UnhookWindowsHookEx()函数将释放的是钩子链中函数SetWindowsHookEx所装入的钩子进程。 hhk: 将要释放的钩子进程的句柄。 III:钩子进程 钩子进程使用函数HookProc;其实HookProc仅仅只是应用程序定义的符号。比如你可以写成KeyBoardHook.但是参数是不变的。Win32 API提供了诸如:CallWndProc、 GetMsgProc、DebugProc、CBTProc、MouseProc、KeyboardProc、MessageProc等函数,对于他们的详细讲解,可以看MSDN我在此只讲解一下KeyBoardHook的含义。 原形:LRESULT CALLBACK KeyBoardHook (int nCode, WPARAM wParam, LPARAM lParam) 说明:钩子进程是一些依附在一个钩子上的一些函数,因此钩子进程只被WINDOWS调用而不被应用程序调用,他们有时就需要作为一个回调函数(CALLBACK)。 参数说明: nCode:钩子代码,钩子进程使用钩子代码去决定是否执行。而钩子代码的值是依靠钩子的种类来定的。每种钩子种类都有他们自己一系列特性的代码。比如对于WH_KEYBOARD, 钩子代码的参数有:HC_ACTION,HC_NOREMOVE。HC_ACTION的意义:参数wParam 和lParam 包含了键盘敲打消息的信息,HC_NOREMOVE的意义:参数wParam 和lParam包含了 键盘敲打消息的信息,并且,键盘敲打消息一直没有从消息队列中删除。(应用程序调用PeekMessage函数,并且设置PM_NOREMOVE标志)。也就是说当nCode等于HC_ACTION时, 钩子进程必须处理消息。而为HC_NOREMOVE时,钩子进程必须传递消息给CallNextHookEx函数,而不能做进一步的处理,而且必须有CallNextHookEx函数的返回值。 wParam:键盘敲打所产生的键盘消息,键盘按键的虚拟代码。 lParam:包含了消息细节。 注意:如果钩子进程中nCode小于零,钩子进程必须返回(return) CallNextHookEx(nCode,wParam,lParam);而钩子进程中的nCode大于零,但是钩子进程并不处理消息, 作者推荐你调用CallNextHookEx并且返回该函数的返回值。否则,如果另一个应用程序也装入WH_KEYBOARD 钩子,那么该钩子将不接受钩子通知并且返回一个不正确的值。 如果钩子进程处理了消息,它可能返回一个非零值去阻止系统传递该信息到其它剩下的钩子或者windows进程。所以最好在钩子进程的最后都返回CallNextHookEx的返回

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值