1. 定义
把一段可执行的代码像参数传递那样传给其他代码,而这段代码会在某个时刻被调用执行,这就叫做回调。换句话说,函数 F1 调用函数 F2 的时候,函数 F1 通过参数给函数 F2 传递了另外一个函数 F3 的指针,在函数 F2 执行的过程中,函数F2 调用了函数 F3,这个动作就叫做回调(Callback),而先被当做指针传入、后面又被回调的函数 F3 就是回调函数。
举个例子:
#include<stdio.h>
#include<softwareLib.h> // 包含Library Function所在Software library库的头文件
int Callback() // Callback Function
{
// TODO
return 0;
}
int main() // Main program
{
// TODO
Library(Callback);
// TODO
return 0;
}
在回调中,主程序把回调函数像参数一样传入库函数。这样一来,只要我们改变传进库函数的参数(传入不同的回调函数实现),就可以通过库实现不同的功能。并且丝毫不需要修改库函数的实现,这就是解耦。
主函数和回调函数是在同一层的,而库函数在另外一层。一般库函数对我们不可见或者不能轻易修改库函数,所以通过传入不同的参数(回调函数)来实现通过修改库函数,让库函数调用普通函数相同的功能,更加安全和常见。
这里,main()、Library()和Callback()函数即前面的 F1、F2和F3函数。
2. 使用场景
如果需要降低耦合度的时候,更应该使用回调函数。
3. 实例
嵌入式C语言中,回调函数一般结合结构体使用。
/*
仅回调函数核心代码
*/
struct oreder_code_desc
{
int order_code_ID;
void (*callback)(int channel, char *SetValue);
};
static struct oreder_code_desc OrderCodeInfo[]={
{DBID_RING_CODE, RingCodeAction}, /*0*/
{DBID_PRV_ORDER_CODE, PrvCodeAction}, /*1*/
};
int OrderCodeMatch(word_t channel, char *matchbuff)
{
int i;
char paramdata[32];
char SetValueBuff[32] = "";
if(NULL == matchbuff || (0 == strcmp(matchbuff, "")))
{
return -1;
}
for(i = 0; i < sizeof(OrderCodeInfo)/sizeof(OrderCodeInfo[0]); i++){
memset(paramdata, 0, sizeof(paramdata));
dbGetParam(OrderCodeInfo[i].order_code_ID, channel, paramdata);
if((0 == strncmp(matchbuff, paramdata, strlen(paramdata))) && (strlen(paramdata) != 0)){
sscanf(matchbuff + strlen(paramdata), "%[^#]", SetValueBuff);
OrderCodeInfo[i].callback(channel,SetValueBuff);
}
}
FV_TRACE("@@@@@@@@********** @KeyBuff [%s], DBID_ORDER_CODE [%s]", matchbuff, paramdata);
return 0;
}