回调函数

回调函数是c语言中最具典型的的指针的应用,整个机制稍微复杂。在现实中有很多应用场景。自己理解的也不是很全面到位,有不对的地方大家多多批评指正。

1、思想:函数参数化。这样就可以模仿C++语言中的重载机制。

2、数据交互。在有些静态动态库中,我们可以调用它们的方法,可是这样的单向调用功能不够强大。

场景1:比方一个用于传输数据的库A,我们的程序B调用A的接口用于传输数据,但是A可能会遇到网络等问题,无法传输,这时可能返回传输失败,对于B处理起来,逻辑就会很麻烦,所以如果,在运行正常的情况下,A库能主动调用B程序的生产数据的接口,问题就会迎刃而解。两边的逻辑复杂度就会降低很多。

场景2:A是底层生产数据的库,B通过不断调用A的生产数据的接口获取数据,但是有些数据可能实时性要求很高,比如报警,不能等到B自然循环来获取。所以需要A库来主动上送报警信息(这就是所谓的事件)。


仔细分析,不管是场景1还是场景2,A作为一个通用的库,往往是事先先开发好的,是没法知道后来的B使用者的具体函数接口的,所以不能够主动调用。这时候,就可以用回调函数来实现。在A库中定义一个接口a1,这个接口就是B以后的调用者要实现的,由于B是按照A的事先规定实现的,所以A就可以调用啦,当然,A需要写一个注册的接口,功能就是让B将自己实现的函数地址赋值给a1。懒,就不写这部分了。直接写一下回调函数的框架就行了,方便以后查看。不对的地方,大家指正哈。

#include <stdio.h>
#include <STDLIB.H>


typedef void(* CallBackFunAdd)(void *p1, void * p2, void *Result);
//CallBackFunAdd 就代表一个 void (void *p1, void * p2, void *Result)这样一个函数类型。


struct complex
{
int iReal;
int iImag;
};

//符合回调接口的规定,所以就是相当于B中回调函数的一个实现
void  addReal(void *pa, void *pb, void *pResult)
{
int a = *(int *)pa;
int b = *(int *)pb;
int *pResult1 = (int*)pResult;
*pResult1 = a + b;

printf("实数加法:%d + %d = %d\n",a,b,pResult1);
}

//符合回调接口的规定,所以就是相当于B中回调函数的一个实现
void addComplex(void *pa, void *pb, void *pResult)
{
complex a =*(complex*)pa;
complex b =*(complex*)pb;
complex *Result =(complex*)pResult;
Result->iReal = a.iReal + b.iReal;
Result->iImag = a.iImag + b.iImag;
printf("复数加法:(%d,%d)+(%d,%d) = (%d,%d)\n",a.iReal,a.iImag,b.iReal,b.iImag,Result->iReal,Result->iImag);
}


//用来执行回调函数,调用者把要调用的函数以‘参数’的形式传进来。
void Call( CallBackFunAdd  pCallBackAdd,void *a,void* b, void *c)
{
printf("执行回调:\n");
pCallBackAdd(a,b,c);
}

void main()
{
int ia = 2;
int ib = 3;
int ic = 0;
Call(addReal,&ia,&ib,&ic);


complex ca;
ca.iReal = 1;
ca.iImag = 2;

complex cb;
cb.iReal = 3;
cb.iImag = 4;


complex cc;
cc.iReal = 0;
cc.iImag =0;
Call(addComplex,&ca,&cb,&cc);
getchar();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值