zoukankan      html  css  js  c++  java
  • 【Callback接口初探】工程化编程实战Callback接口学习笔记

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

    环境:

    • 系统:Manjaro
    • 内核版本:5.4.24
    • gcc 版本:9.2.1
    • VS Code:1.43.0

    任务:

    • 在VS Code下编译运行lab5-1.tar.gz
    • 通过VS Code + GDB调试程序找出quit命令无法运行的bug产生的原因
    • 分析Callback接口的运行机制,总结Callback接口设计的方法

    编译项目

    1. VS Code下进行编译。

      Terminal>Run Build Task,新建tasks.json文件

    2. 因为要进行链接,所以将其中的args改为如下,其他具体VS Code操作见上一篇博客

      "args": [
          "-g", // 编译的时候需要带-g参数,否则无法进入调试
          "${fileDirname}/linktable.c",   // 这里,在menu.c前,先编译linktable.c
          "${file}",
          "-o",
          "${fileDirname}/${fileBasenameNoExtension}" // 输出文件和源代码同名,不带后缀
      ],
      
    3. 或者直接使用gcc进行编译

      $ gcc linktable.c menu.c -o menu
      

      发现错误menu.c:49:8: 警告:隐式声明函数‘strcmp’这是没有包含进string.h导致的

    4. menu.c文件内加入#include <string.h>重新编译

    执行项目

    1. 终端输入./menu执行程序

      $ ./menu
      Input a cmd number > help
      help - Menu List:
      help - Menu List:
      version - Menu Program V1.0
      quit - Quit from Menu Program V1.0
      Input a cmd number > quit
      This is a wrong cmd!
      

      发现程序可以运行,但存在bug,无法识别quit命令。

      接下来进入调试,跟踪程序执行情况。

    准备调试环境

    1. 首先安装配置好VS Code,打开项目,过菜单Run>Add Configuration,选择C++ (GDB/LLDB)>g++ build and debug active file来创建VS Code调试用的launch.json文件。更多操作见上一篇博客

      launch.json大致如下:

      {
          // launch.json
          "version": "0.2.0",
          "configurations": [
              {
                  "name": "gcc build and debug active file",
                  "type": "cppdbg",
                  "request": "launch",
                  "program": "${fileDirname}/${fileBasenameNoExtension}",
                  "args": [],
                  "stopAtEntry": false,
                  "cwd": "${workspaceFolder}",
                  "environment": [],
                  "externalConsole": false,
                  "MIMode": "gdb",
                  "setupCommands": [
                      {
                          "description": "为 gdb 启用整齐打印",
                          "text": "-enable-pretty-printing",
                          "ignoreFailures": true
                      }
                  ],
                  "preLaunchTask": "gcc build active file",
                  "miDebuggerPath": "/usr/bin/gdb"
              }
          ]
      }
      

      配置文件中的stopAtEntry也可以设置为true,这样程序进入调试时,可以自动在main函数设置断点。

    调试修复

    1. 回到menu.c文件,在scanf("%s", cmd);后,也就是输入命令后设置断点。

    2. F5进入调试

    3. cmd添加到WATCH

    4. 先输入help,执行

      可以看到,cmd的内容是字符串help,且p指针指向一个tDataNode,通过deschandler可以看出正确匹配命令,所以输出正常

      输入quit后,cmd正常,但指针p指向的是空结点,所以问题可能出在FindCmd函数内(也可能是命令列表初始化时的问题)。

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

      FindCmd函数通过指针函数SearchCondition作为条件,调用linkTable内的SearchLinkTableNode

    5. SearchCondition添加断点

      发现,在进入两次SearchCondition后,就结束了搜索,前两次分别如下

      但linkTable内,在InitMenuData函数中,确实插入了三个结点,调试时也可以看到。

      由只进入两次条件函数,可以断定问题出在SearchLinkTableNode的边界判定上。

      // SearchLinkTableNode
      while(pNode != pLinkTable->pTail)
      {    
          if(Conditon(pNode) == SUCCESS)
          {
              return pNode;				    
          }
          pNode = pNode->pNext;
      }
      

      SearchLinkTableNode的结束条件判断为pNode != pLinkTable->pTail,但pLinkTable->pTail最后一个结点恰好指向命令列表中的最后一个结点quit,所以循环到最后结点时,无法成功进入。

    6. 将循环判断条件改为pNode != NULL程序即可正常运行

    callback接口的运行机制

    C语言里的Callback机制,靠将函数指针传递到另一函数中,然后在需要触发某个事件的时候调用该方法。这种实现方式简单且灵活,是面向过程的。

    在需要回调的函数中先预留一个函数指针参数,接着在外部定义该具体的被回调函数,在执行时将被回调函数作为指针传入,在回调函数中满足某特定条件后,调用该函数。

    回调机制能减少不同模块之间的耦合程度,简化了用户接口。

    作者:SA19225176,万有引力丶

    参考资料来源:USTC SE2020高级软件工程

  • 相关阅读:
    CSS3 Flex布局整理(二)-容器属性
    CSS3 Flex布局整理(一)
    .Net Core中文编码问题整理
    Karma:1. 集成 Karma 和 Jasmine 进行单元测试
    Protractor
    翻译: TypeScript 1.8 Beta 发布
    webpack 插件: html-webpack-plugin
    How I came to find Linux
    翻译:Angular 2
    在 Angular 中实现搜索关键字高亮
  • 原文地址:https://www.cnblogs.com/Axi8/p/12519205.html
Copyright © 2011-2022 走看看