回调函数
1、函数类型基础
函数三要素:名称、参数、返回值 C语言中的函数有自己特定的类型 |
C语言中通过typedef为函数类型重命名 typedef type name(parameter list) typedef int f(int, int); typedef void p(int); |
函数指针 |
函数指针用于指向一个函数 函数名是执行函数体的入口地址 1)可通过函数类型定义函数指针:FuncType* pointer; 2)也可以直接定义:type(*pointer)(parameter list); pointer为函数指针变量名 type为指向函数的返回值类型 parameterlist为指向函数的参数类型列表
|
|
2、函数指针做函数参数
回忆指针做函数参数 一级指针做函数参数、二级、三级 |
当函数指针做为函数的参数,传递给一个被调用函数, 被调用函数就可以通过这个指针调用外部的函数,这就形成了回调 |
现在这几个函数是在同一个文件当中 假如 int libfun(int (*pDis)(int a, intb)) 是一个库中的函数,就只有使用回调了,通过函数指针参数将外部函数地址传入 来实现调用
函数add的代码作了修改,也不必改动库的代码,就可以正常实现调用 便于程序的维护和升级 |
3、函数指针正向调用
被调用函数和主调函数在同一文件中(用来教学,没有任何意义) |
2、函数指针做函数参数 被调用函数和主调函数不在同一个文件中、模块中。 难点:理解被调用函数是什么机制被调用起来的。框架 框架提前设置了被调用函数的入口(框架提供了第三方模块入口地址的集成功能) 框架具备调用第三方模块入口函数 |
typedef int (*EncDataFunc)(unsignedchar *inData,int inDataLen,unsigned char *outData,int*outDataLen,void *Ref, int RefLen);
int MyEncDataFunc(unsigned char*inData,int inDataLen,unsigned char *outData,int *outDataLen,void*Ref, int RefLen) { int rv = 0; char *p = "222222222222"; strcpy(outData, p); *outDataLen = strlen(p); return rv; }
int Send_Data(EncDataFuncencDataFunc, unsigned char *inData, int inDataLen, unsigned char*outData, int *outDatalen) { int rv = 0; if (encDataFunc != NULL) { rv = encDataFunc(inData,inDataLen, outData, outDatalen, NULL, 0); if (rv != 0) { printf("func encDataFunc()err.\n"); return rv; } } return rv; }
int main() { int rv = 0;
EncDataFunc encDataFunc = NULL; encDataFunc = MyEncDataFunc;
// 第一个调用 { unsigned char inData[2048]; int inDataLen; unsigned char outData[2048]; int outDatalen; strcpy(inData, "1111"); inDataLen = strlen(inData); rv = encDataFunc(inData,inDataLen,outData, &outDatalen, NULL, 0); if (rv != 0) { printf("edf err .....\n"); } else { printf("edf ok \n"); printf("%s \n",outData); } }
{ unsigned char inData[2048]; int inDataLen; unsigned char outData[2048]; int outDatalen; strcpy(inData, "3333"); inDataLen = strlen(inData); rv = Send_Data(MyEncDataFunc,inData, inDataLen, outData, &outDatalen); if (rv != 0) { printf("func Send_Dataerr:%d", rv); return rv; } printf("%s \n",outData); }
getchar(); } |
4、函数指针反向调用
回调函数
利用函数指针实现的一种调用机制 |
具体任务的实现者,可以不知道什么时候被调用 |
回调函数是利用函数指针实现的一种调用机制
回调机制原理 当具体事件发生时,调用者通过函数指针调用具体函数 回调机制的将调用者和被调函数分开,两者互不依赖 任务的实现和 任务的调用 可以耦合 (提前进行接口的封装和设计) |
需要重新审视dll和其他第三方厂商接口之间的关系 动态库可以集成第三方厂商的业务功能 动态库(框架)不经常改动,能兼容后来的业务模型,2010年写的代码能调用2020写的代码,用到多态 动态库和第三方业务模型模块之间 松耦合 |
//动态库变成框架需要做的工作 //1 第三方业务入口传进来(回调函数的入口地址传进来)
//2 加密解密 业务模型抽象 //实现动态库 加密解密业务模型抽象 通过定义函数指针类型;函数指针做函数参数实现 |
|