前言
回调函数常见于某些开源库的应用中,比如我已试用过的sqlite3开源数据库int sqlite3_exec(sqlite3* pDB, const char *sql, sqlite_callback callback, void*para, char** errMsg),
libcurl开源库curl_easy_setopt(m_curl,CURLOPT_PROGRESSFUNCTION,pCURL_CallBack);
回调函数基于用户需求,不基于开发需求
机制
⑴定义一个回调函数;
⑵提供函数实现的一方在初始化的时候,将回调函数的函数指针注册给调用者;
⑶当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理。
要求
假设我需要获取本地的时间,现在模拟两种情况
1、我作为开发者,知道如何获取
2、我作为使用者,不会获取,需要使用某种开源库提供的方法
示例
1、我作为开发者
#include <Windows.h>
#include <iostream>
#include <time.h>
using namespace std;
void GetLocalTime(char *cTime,char *cDate)
{
time_t t;
time(&t);
struct tm *tim;
tim = localtime(&t);
if (NULL != cTime)
{
ZeroMemory(cTime,strlen(cTime));
}
if (NULL != cDate)
{
ZeroMemory(cDate,strlen(cDate));
}
sprintf(cTime,"%d:%d:%d",tim->tm_hour,tim->tm_min,tim->tm_sec);
sprintf(cDate,"%d-%d-%d",tim->tm_year+1900,tim->tm_mon+1,tim->tm_mday);
}
int main()
{
char cTime[1024] = {"hello world"};
char cDate[1024] = {0};
GetLocalTime(cTime,cDate);
cout << cDate << endl;
cout << cTime << endl;
return 0;
}
上面这段代码实现了获取本地时间并按照开发需求打印到屏幕上
(我作为开发人员,已知晓如何直接获取时间,我获得时间后按照本次需求,将时间打印在屏幕上)
结果:
2、我做为使用者
(以下为模拟现实使用者需求)
现在我需要获取自己电脑上的时间信息,我需要时间信息干嘛呢?我也不清楚,看具体需求,也就是说,我要通过某种方法获取时间而不需要知道那个方法是如何做的,我找到一个开源库,他提供给我一个方法,我可以通过该方法获取时间信息
(以下代码为使用回调函数情形)
#include <Windows.h>
#include <iostream>
#include <time.h>
using namespace std;
//定义回调函数
int mycall(char *cMyTime,char * cMyDate)
{
char cTimeDetail[1024] = {0};
sprintf(cTimeDetail,"当前的详细时间:%s %s",cMyDate,cMyTime);
cout << cTimeDetail << endl;
return TRUE;
}
int main()
{
GetLocalTime(mycall);
return 0;
}
代码中的
int mycall(char *cMyTime,char * cMyDate)
{
char cTimeDetail[1024] = {0};
sprintf(cTimeDetail,"当前的详细时间:%s %s",cMyDate,cMyTime);
cout << cTimeDetail << endl;
return TRUE;
}
函数就是回调函数,该函数类型,格式为固定格式,我作为使用者需要根据函数提供者的要求去调用
那么开发者的回调函数是怎么实现的呢?
//回调函数类型
typedef int (*MyCallBack)(char *cTime,char *cDate);
void GetLocalTime(MyCallBack pCall)
{
time_t t;
time(&t);
struct tm *tim;
tim = localtime(&t);
char cTime[1024] = {0};
char cDate[1024] = {0};
sprintf(cTime,"%d:%d:%d",tim->tm_hour,tim->tm_min,tim->tm_sec);
sprintf(cDate,"%d-%d-%d",tim->tm_year+1900,tim->tm_mon+1,tim->tm_mday);
pCall(cTime,cDate);
}
上面这段代码就是开发者实现回调函数的方法
pCall(cTime,cDate); 这句是核心
下面给出全部代码(下面代码可编译运行)
#include <Windows.h>
#include <iostream>
#include <time.h>
using namespace std;
//回调函数类型
typedef int (*MyCallBack)(char *cTime,char *cDate);
void GetLocalTime(MyCallBack pCall)
{
time_t t;
time(&t);
struct tm *tim;
tim = localtime(&t);
char cTime[1024] = {0};
char cDate[1024] = {0};
sprintf(cTime,"%d:%d:%d",tim->tm_hour,tim->tm_min,tim->tm_sec);
sprintf(cDate,"%d-%d-%d",tim->tm_year+1900,tim->tm_mon+1,tim->tm_mday);
pCall(cTime,cDate);
}
//定义回调函数
int mycall(char *cMyTime,char * cMyDate)
{
char cTimeDetail[1024] = {0};
sprintf(cTimeDetail,"当前的详细时间:%s %s",cMyDate,cMyTime);
cout << cTimeDetail << endl;
return TRUE;
}
int main()
{
GetLocalTime(mycall);
return 0;
}
看下结果:
总结
回调函数一般做为较为复杂函数的参数,那个复杂的函数可能会处理多个数据,但是使用者可能不需要那么多,因此提供回调函数,将用户需要的数据做为回调函数参数返回,让使用者能根据需求灵活使用复杂函数的数据