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

1.实验要求

  • 在VSCode下编译运行lab5-1.tar.gz 即http://pan.baidu.com/s/1pJ0qAIv

  • 通过VSCode+GDB调试程序找出quit命令无法运行的bug产生的原因

  • 分析callback接口的运行机制,总结callback接口设计的方法

 

2.实验过程:

 

编译报错:

工程化编程实战callback接口学习笔记_第1张图片

 

 

 

 

源代码定位问题:

工程化编程实战callback接口学习笔记_第2张图片

 

 p == NULL为真的情况下,程序会报错wrong cmd。因为p是FindCmd函数的返回值,因此找到FindCmd的函数定义,如下:

工程化编程实战callback接口学习笔记_第3张图片

 

 

发现FindCmd只是对SearchLinkTableNode进行了包装,因此继续查看SearchLinkTableNode()函数的定义

工程化编程实战callback接口学习笔记_第4张图片

 

光看这里我们发现有可能是pLinkTable或者Condition为空,也可能是执行到函数末尾返回空。首先返回menu.c查看pLinkTable是否有可能为空。因为pLinkTable实际上就是menu.c的全局变量head,又发现head在InitMenuData函数中进行了初始化,如下所示。因此pLinkTable不为空。

 

工程化编程实战callback接口学习笔记_第5张图片

 

 

 

 

 

又因为Condition函数同样在menu.c给出,因此NULL是在函数末尾处返回的。所以我们需要去研究一下链表是怎么构造的。通过上图InitMenuData()函数,我们得知构造链表是通过AddLinkTableNode()进行的。如下:

 

工程化编程实战callback接口学习笔记_第6张图片

 

我们发现,每次插入节点之后,pTail指向的是最后一个节点,所以是while循环的判断条件出现了问题,导致pNode没有与链表的最后一个节点比较,导致我们的quit命令没有反应。综上,修改while语句的判断条件即可:

 

 

 

之后重新编译运行:

 

 顺利退出。

 

3.分析callback接口的运行机制

1 回调函数的运行机制

回调函数是指使用者自己定义一个函数,实现这个函数的程序内容,然后把这个函数(入口地址)作为参数传入别人(或系统)的函数中,由别人(或系统)的函数在运行时来调用的函数。函数是你实现的,但由别人(或系统)的函数在运行时通过参数传递的方式调用,这就是所谓的回调函数。简单来说,就是由别人的函数运行期间来回调你实现的函数。

 工程化编程实战callback接口学习笔记_第7张图片

 

 

这一设计允许了底层代码调用在高层定义的子程序。C语言中回调函数主要通过函数指针的方式实现。

本例中使用了回调函数的机制,本例中FindCmd(tLinkTable * head, char * cmd)调用SearchLinkTableNode(head,SearchCondition)函数,而SearchLinkTableNode通过调用了回调函数condition()。实现函数调用中,函数调用了“调用函数”,再在其中进一步调用被“调用函数”。相比于主函数直接调用“被调函数”,这种方法为使用者,而不是开发者提供了灵活的接口。另外,函数入口可以像变量一样设定同样为开发者提供了灵活性。

2 Callback接口设计的方法

  • 回调函数传入的参数是函数指针,函数指针用来调用其所指向的函数,调用者和被调用者分开,调用者并不关心谁是被调用者,可以对特定的事件或条件进行响应,当发生某种事件时系统或其他函数会自动调用定义的一段函数。
  • 将符合要求的参数以及函数指针作为调用函数的参数。当用户调用时,只需要将函数指针指向不同的函数即可

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