深入理解Callback函数

在之前menu代码基础上,通过使用回调函数,使得降低业务代码和通用工具代码进行解耦。

工具代码基本数据结构及其操作分析

首先是tLinkTableNode,即LinkTableNode:

struct LinkTableNode
{
    struct LinkTableNode * pNext;
};

在此数据结构中,仅有一个指向自身类型元素的指针。

再查看tLinkTable ,即LinkTable

struct LinkTable
{
    struct LinkTableNode *pHead;
    struct LinkTableNode *pTail;
    int			SumOfNode;
    pthread_mutex_t mutex;
};

此数据结构的作用是用来标识业务数据的起始位置。

在linktable.c文件中,定义了对此数据结构的增删查等基本操作。现重点关注其查找操作。

tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Condition(tLinkTableNode * pNode, void * args), void * args);

在此函数中,第二个入参为一个函数指针,传入一个Condition类型的函数,即回调函数,通过将指定的函数传入,使用业务定制化查询条件进行查询,进行解耦,将工具代码和业务代码逻辑分开。

回调函数

回调函数就是一个通过函数指针来调用指定的函数。将函数的指针作为参数传递给另一个函数,当函数使用这个指针时,会调用此指针所指向的函数,即回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
在此项目中,可查看回调函数SearchCondition的地址:
在这里插入图片描述

业务代码分析

首先在menu.c文件中,数据结构tDataNode定义如下:

typedef struct DataNode
{
    tLinkTableNode head;
    char*   cmd;
    char*   desc;
    int     (*handler)();
} tDataNode;

通过InitMenuData函数,形成如下图的数据节点:

在这里插入图片描述

使用FindCmd函数查找指定节点:

tDataNode* FindCmd(tLinkTable * head, char * cmd)
{
    return  (tDataNode*)SearchLinkTableNode(head, SearchCondition, (void*)cmd);
}

FindCmd中又调用了SearchLinkTableNode,而SearchLinkTableNode的第二个参数则是回调函数SearchCondition,在SearchLinkTableNode中调用传入的回调函数:

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;
}

现查看回调函数定义:

int SearchCondition(tLinkTableNode * pLinkTableNode, void * args)
{
    char * cmd = (char*) args;
    tDataNode * pNode = (tDataNode *)pLinkTableNode;
    if(strcmp(pNode->cmd, cmd) == 0)
    {
        return  SUCCESS;  
    }
    return FAILURE;	       
}

通过转换指针的类型,屏蔽通用库对业务数据的访问,隔离开来。因为tDataNode中第一个数据类型是tLinkTableNode,传入的参数原始类型是tDataNode,只是转成了tLinkTableNode,用于数据结构的建立,因此可将传入的tLinkTableNode类型的参数转回为tDataNode类型,使用节点中的数据进行比较,完成查询的功能。由此可以看出,查找的条件是由业务方提供,可以根据自己的需求自定义实现,进行隔离

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值