工程化编程实战callback接口学习笔记

工程化编程实战callback接口学习笔记

编译

  • 首先缺少头文件,在munu.c头部添加语句#include
  • 使用vscode打开实验文件夹,打开terminal,输入指令:gcc -o test linktable.c menu.c
  • ./test命令执行可执行文件
    image.png
  • 输出了错误提示
  • 查看mian()函数
    工程化编程实战callback接口学习笔记_第1张图片
  • 可以判断是语句:tDataNode *p = FindCmd(head, cmd);使得p称为了空指针。

调试

  • 知道了问题所在,接下来进行调试
  • 首先,添加-g重新编译。gcc -g linktable.c menu -o test
  • 输入gdb test进行调试
  • 查看main()函数中tDataNode *p = FindCmd(head, cmd);位置,在101行处。
  • 打断点,输入命令行```break 101``
  • 运行程序
    工程化编程实战callback接口学习笔记_第2张图片
  • 输入s进入函数内部,并且使用n逐行执行
    工程化编程实战callback接口学习笔记_第3张图片
  • 可以看到,函数返回了NULL
  • 查看代码
tDataNode *p = FindCmd(head, cmd);
  • 这里将InitMenuData()构造的指针,和输入的指令作为参数,下面看看head指针指向的内容。
int InitMenuData(tLinkTable ** ppLinktable)
{
    *ppLinktable = CreateLinkTable();
    tDataNode* pNode = (tDataNode*)malloc(sizeof(tDataNode));
    pNode->cmd = "help";
    pNode->desc = "Menu List:";
    pNode->handler = Help;
    AddLinkTableNode(*ppLinktable,(tLinkTableNode *)pNode);
    pNode = (tDataNode*)malloc(sizeof(tDataNode));
    pNode->cmd = "version";
    pNode->desc = "Menu Program V1.0";
    pNode->handler = NULL; 
    AddLinkTableNode(*ppLinktable,(tLinkTableNode *)pNode);
    pNode = (tDataNode*)malloc(sizeof(tDataNode));
    pNode->cmd = "quit";
    pNode->desc = "Quit from Menu Program V1.0";
    pNode->handler = Quit; 
    AddLinkTableNode(*ppLinktable,(tLinkTableNode *)pNode);
 
    return 0; 
}
  • 可以看出,构造了三个节点,help、version、quit,FindCmd()调用了SearchLinkTableNode(),他的参数有一个是函数返回值提供,查看下SearchCondition()函数的实现
tDataNode* FindCmd(tLinkTable * head, char * cmd)
{
    return  (tDataNode*)SearchLinkTableNode(head,SearchCondition);
}
  • searchcondition函数的作用是查看指针指向节点的cmd元素的值是否为我们输入时指定的值,是就返回SUCCESS(0)
int SearchCondition(tLinkTableNode * pLinkTableNode)
{
    tDataNode * pNode = (tDataNode *)pLinkTableNode;
    if(strcmp(pNode->cmd, cmd) == 0)
    {
        return  SUCCESS;  
    }
    return FAILURE;	       
}
  • 根据刚才调试的结果,观察while语句,循环体是若节点的cmd元素值为我们指定的cmd值时,就返回该节点。所以,如果pNode != NULL就应该继续循环;
tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode))
{
    if(pLinkTable == NULL || Conditon == NULL)
    {
        return NULL;
    }
    tLinkTableNode * pNode = pLinkTable->pHead;
    while(pNode != pLinkTable->pTail)
    {    
        if(Conditon(pNode) == SUCCESS)
        {
            return pNode;				    
        }
        pNode = pNode->pNext;
    }
    return NULL;
}
  • 至此,重新编译运行
    工程化编程实战callback接口学习笔记_第4张图片
  • 可以看到问题解决了

分析callback接口运行机制

  • 回调机制通过像函数传递函数的指针作为参数,调用了一个外部实现的函数,这种方式具有很强的灵活性。
    工程化编程实战callback接口学习笔记_第5张图片
  • 实现方式:
    • 首先函数形参设置为函数指针,回调函数的形式应该与指针指向函数的形式一致
    • 把回调函数像参数一样传入中间函数。
    • 这样就能实现回调

你可能感兴趣的:(工程化编程实战callback接口学习笔记)