目录
回调函数是一个通过函数指针调用的函数。如果你把函数的指针作为参数给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
二、实现机制
1.定义一个回调函数
在本实验中回调函数的具体实现代码如下图所示,该代码用于判断当前链表节点中的数据是否与给定的字符串相同,如果相同则返回 SUCCESS,否则返回 FAILURE。
int SearchCondition(tLinkTableNode * pLinkTableNode, void * args)
{
char * cmd = (char*) args;
tDataNode * pNode = (tDataNode *)pLinkTableNode;
if(strcmp(pNode->cmd, cmd) == 0)
{
return SUCCESS;
}
return FAILURE;
}
Condition函数作为callback函数允许用户进行自定义,同时SearchLinkTableNode函数和SearchCondition函数中都添加了一个void*类型的额外参数,将两个模块在一定程度上解耦合的同时,提高了模块的通用性。
2.将回调函数的函数指针注册给调用者
在menu.c文件中FindCmd调用SearchLinkTableNode函数,SearchCondition作为Condition函数的具体实现,被当作SearchLinkTableNode函数中的其中一个参数,传入到函数内并进行后续的处理,代码如下:
tDataNode* FindCmd(tLinkTable * head, char * cmd)
{
return (tDataNode*)SearchLinkTableNode(head, SearchCondition, (void*)cmd);
}
3.当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理
在本实验中,linktable.c文件中的SearchLinkTableNode接口使用了callback函数,SearchLinkTableNode函数属于调用者,而Condition函数作为SearchLinkTableNode函数的参数,属于callback函数。利用callback函数参数使Linktable的查询接口更加通用,有效地提高了接口的通用性。查询接口代码如下:
tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable,
int Condition(tLinkTableNode * pNode, void * args),
void * args)
{
if(pLinkTable == NULL || Condition == NULL)
{
return NULL;
}
tLinkTableNode * pNode = pLinkTable->pHead;
while(pNode != NULL)
{
if(Condition(pNode, args) == SUCCESS)
{
return pNode;
}
pNode = pNode->pNext;
}
return NULL;
}
总结
回调函数就是允许用户把需要调用的函数的指针作为参数传递给一个函数,以便该函数在处理相似事件的时候可以灵活的使用不同方法。它增强了程序的通用性、灵活性,并在一定程度实现了代码的解耦。