理解
函数指针
指向函数的指针。比如:
理解函数指针的伪代码- void (*p)(int type, char *data); // 定义一个函数指针p
- void func(int type, char *data); // 声明一个函数func
- p = func; // 将指针p指向函数func
- p(1,"test"); // 调用方式1
- (*p)(1,"test"); // 调用方式2
复制代码 回调函数和回调
比如,B把自己函数cbkFunc()的地址告诉A,A在运行过程中执行cbkFunc()。则
回调函数:指B的函数cbkFunc();
注册回调函数:指B把函数cbkFunc()的地址告诉A;
回调:指A在运行过程中执行cbkFunc()。
code
- 无头文件.h
- 为了方便模块A和B写在了一个.c文件中
- 打印log的函数见参考博客[3],可以直接替换为printf()
FunctionPointTest.c- /*
- * 理解函数指针和回调函数
- *
- * 假设需求:A要进行某项运动,有开始、正在做、结束3个状态,
- * B需要关注这3个状态
- *
- * 实现方案:A提供一个回调函数注册接口,在程序开始运行时,
- * B向A注册回调函数,A以回调函数的形式通知B
- *
- * 为了简便A和B写在一个文件里
- */
- #include "D:\MyFiles\MyLog\WindowsC\mylog.h"
- #include <stdio.h>
- #include <windows.h>
- // A和B的共同定义,一般是A的一个头文件,B会包含这个头文件:
- typedef enum ENUM_EVENT {
- E_EVENT_START,
- E_EVENT_DOING,
- E_EVENT_FINISH,
- } EnumEvent;
- typedef void (*EVENT_CBK)(EnumEvent type, char *data);
- int regEventCbk(EVENT_CBK cbk);
- // A的实现
- #define TAGA "[MODULE_A]"
- static EVENT_CBK gSendEvent = NULL;
- int regEventCbk(EVENT_CBK cbk) {
- if (cbk == NULL) {
- return -1;
- }
- gSendEvent = cbk;
- LOGI("%s{有人注册了回调函数:%X, 地址:%p}", TAGA, *gSendEvent, gSendEvent);
- return 0;
- }
- void doing() {
- gSendEvent(E_EVENT_DOING, "进行中..."); // 调用方式1
- Sleep(1000);
- }
- void runA() {
- LOGI("%s{我是A}", TAGA);
- if (gSendEvent == NULL) {
- LOGW("%s{B不关心我}", TAGA);
- return;
- }
- (*gSendEvent)(E_EVENT_START, "我开始了哟"); // 调用方式2
- doing();
- (*gSendEvent)(E_EVENT_FINISH, "我好了");
- }
- // B的实现
- #define TAGB "[MODULE_B]"
- long long int gAStart = 0;
- long long int gAFinish = 0;
- void eventStartHandler(char *data) {
- gAStart = GetTickCount();
- LOGI("%s{A:%s}{%lld}", TAGB, data, gAStart);
- }
- void eventDoingHandler(char *data) {
- LOGI("%s{A:%s}", TAGB, data);
- }
- void eventFinishHandler(char *data) {
- long long int aDurS = 0;
- gAFinish = GetTickCount();
- LOGI("%s{A:%s}{%lld}", TAGB, data, gAFinish);
- aDurS = (gAFinish - gAStart)/1000;
- LOGI("%s{A %llds}", TAGB, aDurS);
- if (aDurS < 10) {
- LOGI("%s{A 真快}", TAGB);
- }
- }
- void onEvent(EnumEvent type, char *data) {
- switch (type) {
- case E_EVENT_START:
- eventStartHandler(data);
- break;
- case E_EVENT_DOING:
- eventDoingHandler(data);
- break;
- case E_EVENT_FINISH:
- eventFinishHandler(data);
- break;
- default:
- break;
- }
- }
- void careA() {
- LOGI("%s{我的回调函数地址:%p}", TAGB, onEvent);
- regEventCbk(onEvent);
- }
- void runB() {
- LOGI("%s{我是B}", TAGB);
- careA();
- }
- int main() {
- LOGI("{start}");
- runB();
- runA();
- return 0;
- }
复制代码 运行结果

可优化点
.
参考博客
[1] https://zhuanlan.zhihu.com/p/162578969
[2] https://blog.csdn.net/zhou8201/article/details/100700479
[3] https://blog.csdn.net/qq_31300101/article/details/130190026?spm=1001.2014.3001.5502
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |