工程化编程实战callback接口学习笔记
-
在VSCode下编译运行lab5-1
- 运行代码时发现输入quit命令后,显示“This is a wrong cmd!”
-
通过VSCode+GDB调试程序找出quit命令无法运行的bug产生的原因
-
int main() { InitMenuData(&head); /* cmd line begins */ while(1) { printf("Input a cmd number > "); scanf("%s", cmd); tDataNode *p = FindCmd(head, cmd); if( p == NULL) { printf("This is a wrong cmd!\n "); continue; } printf("%s - %s\n", p->cmd, p->desc); if(p->handler != NULL) { p->handler(); } } }
- 发现bug后,通过查看main函数代码,发现问题出在FindCmd()函数,此函数的功能为搜索匹配的cmd,显然其未能成功搜索到quit命令。根据InitMenuData()函数初始化命令的时候,将quit命令放在链表的末尾,根据经验可以猜测链表末尾未与输入的cmd匹配。
- 下面使用gbd调试来具体分析代码
- 进入调试后使用l输入list查看代码,在FindCmd()函数那一行打上断点,执行代码
- 发现进入FindCmd函数后,会进而执行SearchLinkTableNode()函数,进入while循环中,,通过Conditon()函数判断链表结点中的cmd与输入的cmd是否相等。这里condition()函数是一个参数,具体的实现由SearchConditon()完成。while循环执行两次便不满足循环条件了,返回NULL。可见while循环少了一次。
- 分析while循环的条件,pNode!=pLinkTable->pTail,因为quit命令所在的结点刚好就是链表的pTail结点,所以该结点被排除在外。我们可以通过修改while循环的条件为pNode!=NULL来排除此bug。
- 分析callback接口的运行机制,总结callback接口设计的方法
- 一般情况下,应用程序会时常通过API调用库里预先准备好的函数,但是有些库函数却要求应用先传给它一个函数,好在合适的时候的调用,以完成目标任务,这个被传入的、后又被调用的函数就称为回调函数。
- 对于lab5-1中,SearchCondition()就是回调函数。作为库函数的SearchLinkTableNode()函数,需要先传入一个Condition()函数才会得以执行。Condition用于比较某个链表结点中的cmd是否与输入的cmd相同。使用这样的回调函数,就可以不用保持库函数中链表的结构、变量名称与我们创建的链表结构、变量名称一致。使库函数的应用更加灵活,降低了耦合性。