什么是回调函数?--------- 被动调用的函数 or 前人写的代码模块内部,可以调用你现在写的函数。
我们最常写的函数,是为了完成某个功能 而写的, 然后在需要的时候 直接用函数名+()进行调用,得到返回值。
回调函数会稍稍有点区别,在说这个之前呢,我们先了解下回调函数重要的一个前置知识点:函数指针
int*, char* , char**,...这些属于基础类型的指针,函数指针就是 指向函数的指针
函数的组成:返回值类型 函数名称(函数参数){
函数体
}
如果要定义一个函数指针,我们需要 返回值类型 函数名称 和 函数参数, 最重要的是 返回值类型和函数参数,我们看一个
最简单的函数指针
void print(void){
printf("我挺suai!\n");
}
print就是一个函数指针,这个函数指针的 返回值类型:void , 参数类型:void
但是 这个函数指针属于常量,为什么呢,因为这个函数是已经定义了,所以,我们不能将print再指向其他的同类型函数了,会报"表达式必须是可修改的左值 "的错误
自定义函数指针的方式 函数声明 加个 *,只声明不定义,要求 返回值类型和函数参数类型、个数必须一致的这种形式的函数。
如 : void (*Func)(void);
这里 Func 可以指向任意一个 函数返回值类型为:void 函数参数为void 的函数了,比如让Func指向上面的print函数:
Func = print;//常量值可以赋值给变量
这样赋值之后 Func就等价于print了,如果我们进行调用:
Func(); //等价于 print();
我们可以用 关键字 typedef 将一个函数指针重命名一个函数类型,如:
typedef void (*pFunc)(void);
这样的话,我们就有一个 函数返回值类型为:void 函数参数为:void的函数指针类型可用了
我们可以像定义普通的变量一样:
pFunc pfunc1; pFunc pfunc2;
pfunc1 = print; pfunc2 = print
调用时:pfunc1(); pfunc2(); print(); 这三个函数的调用是等价的
好了,相信大家对函数指针有了初步了解了吧,接下来我们来说主题---------回调函数
回调函数必备的一个特性:函数形参是 函数指针类型
大家看到有函数的函数形参是 函数指针类型的话,没错 这就是回调函数
回调函数的机制: 开发者 根据 接口形参的函数指针类型 编写相同类型的函数,将函数名作实参,传递给接口进行调用,
接口内部对函数指针参数传参调用,传递数据,达到已经成型固定的、封装的代码块,可以调用后面开发者写的代码,并传递数据出去的效果。非常实用。
接下来给大家举个例子:
2000年封装的模块:
typedef void (*pFunc)(int errnum/*错误号*/,const char * info/*错误信息*/)
void GetErrorInfo(pFunc CallBackFunc) //or void GetLogInfo(void (*CallBackFunc)(int errnum/*错误号*/,const char * info/*错误信息*/))
{
int errnum = 0;
char errstr[128] = "hello 我错了 我骄傲";
..
..
if (CallBackFunc!=NULL){
CallBackFunc(errnum, errstr);
return;
}
}
2020年写的功能:
void ErrorInfo(int errnum/*错误号*/,const char * info/*错误信息*/)
{
printf("errnum:%d\t errorInfo:%s\n", errnum, info);
//写入日志 or 发送给日志服务器
}
//业务功能代码
void mainFunc(){
..
GetErrorInfo(ErrorInfo)
..
}
新写的函数被已经封装的接口进行了调用,这就是回调函数,回调函数具体作用,大家可以看下win32创建windows窗口的程序,消息回调函数,windows最最重要的机制 消息循环机制 就是用了回调函数,通过回调函数 我们可以将协议号和对应 的函数指针用map或者其他的容器进行注册,然后建立一个消息循环,收到消息 解析协议号,在容器中找到对应的协议号,通过指针函数调用相应的处理函数
C++游戏服务器开发交流群:136961182,欢迎各位朋友一起交流