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

实验要求

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

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

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

置环境

1 安装gcc

首先在Windows下的VSCode下搭建C开发环境,这里使用mingw-w64配置gcc环境,文件链接:https://sourceforge.net/projects/mingw-w64/

将文件解压,我这里放的是C:\Program Files\mingw-w64\MinGW\bin文件夹

 

2 在系统变量中的Path添加环境变量

 

打开命令行窗口,输入gcc -v看见gcc版本相关信息,安装完成

 

3 安装VSCode,并安装C/C++调试器

 

环境配置完成

二 用VSCode运行示例代码

在终端输入:

gcc -o test menu.c linktable.c

 

提示有两个错误

错误1:缺少函数strcmp头文件string.h声明,在menu.c中添加string.h头文件

错误2:缺少pthread头文件,该问题比较复杂,具体解决方法参考https://blog.csdn.net/CSDN_WHB/article/details/81475233

添加完pthread库后在终端输入:

gcc -o test menu.c linktable.c -lpthread

 

成功生成目标程序

 

输入./test运行程序,输入help,quit指令

 

Quit命令提示是一个错误的指令。

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

找到main输入指令位置,cmd是一个全局变量,由这里我们可以知道p为空,所以会错误,

 

继续查看FindCmd函数,这个函数是通过给定的链表和cmd值返回数据节点的地址,函数代码如下

 

该函数调用了SearchLinkTableNode,继续查看SearchLinkTableNode函数

 

该函数的实现大概是,从链表头开始遍历,对比链表节点,找到符合节点就返回该节点指针,失败则返回null

这里链表不为空且condition函数存在,应该是循环结束没有返回节点,执行最后的return null语句

仔细分析循环体:while(pNode != pLinkTable->pTail)该循环条件表示节点不为表尾则继续循环,但是我们查看InitMenuData(tLinkTable ** ppLinktable)函数发现,quit节点刚好就是链表的尾,所以遍历到该节点时没有访问就跳出循环了,因此这里返回了null

 

 

 

我们将判断条件改为

while(pNode != NULL)

重新执行,程序成功运行

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

1 回调函数的运行机制

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

 

 

 

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

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

2 Callback接口设计的方法

  • 回调函数传入的参数是函数指针,函数指针用来调用其所指向的函数,调用者和被调用者分开,调用者并不关心谁是被调用者,可以对特定的事件或条件进行响应,当发生某种事件时系统或其他函数会自动调用定义的一段函数。
  • 将符合要求的参数以及函数指针作为调用函数的参数。当用户调用时,只需要将函数指针指向不同的函数即可
posted @ 2020-03-19 13:19  二仙桥下摸鱼  阅读(244)  评论(0编辑  收藏  举报