当前位置: 首页 > news >正文

回调函数的理解和例子

嵌入式设备对象管理案例分析与实现

代码分析

这是一个嵌入式系统中设备对象管理的结构体设计,采用了面向对象的思想在C语言中实现。让我通过一个简单的LED控制案例来详细解释。

案例:LED设备控制

1. 定义设备结构体和回调函数类型

#include <stdio.h>
#include <stdint.h>
#include <string.h>// 定义回调函数类型
typedef void (*run_t)(void* argument);// 定义回调函数数量
#define CALLBACKCOUNT 6// 设备对象结构体
struct OBJ_DEV_T 
{char     instance_name[16];          // 实例名称uint8_t  is_initialized;             // 初始化状态标志run_t    function[CALLBACKCOUNT];    // 回调函数数组uint8_t  funskip;                    // 函数跳过标志// 对外方法封装struct{void (*InitHardWare)(void);        // 初始化硬件void (*InitDeHardWare)(void);      // 反初始化硬件void (*Wakup)(struct OBJ_DEV_T* DevInst); // 唤醒设备void (*Sleep)(struct OBJ_DEV_T* DevInst); // 休眠设备void (*Run)(struct OBJ_DEV_T* DevInst, const char *name, void* argument); // 运行函数void (*CreateRun)(struct OBJ_DEV_T* DevInst, const char *name, void (*fun)(void* argument)); // 创建运行函数} method;
};

2. 创建LED控制回调函数

// LED开启回调函数
void LED_On(void* argument) {printf("LED turned ON\n");// 实际硬件操作代码会在这里
}// LED关闭回调函数
void LED_Off(void* argument) {printf("LED turned OFF\n");// 实际硬件操作代码会在这里
}// LED闪烁回调函数
void LED_Blink(void* argument) {int times = *(int*)argument;printf("LED blinking %d times\n", times);// 实际硬件操作代码会在这里
}

3. 实现设备对象创建函数

// 设备对象创建函数
struct OBJ_DEV_T* CreateOBJ_DEV(const char* name, run_t* callbacks) {// 分配内存struct OBJ_DEV_T* new_dev = (struct OBJ_DEV_T*)malloc(sizeof(struct OBJ_DEV_T));// 设置实例名称strncpy(new_dev->instance_name, name, 15);new_dev->instance_name[15] = '\0'; // 确保字符串终止// 初始化标志new_dev->is_initialized = 0;new_dev->funskip = 0;// 设置回调函数if(callbacks) {for(int i = 0; i < CALLBACKCOUNT; i++) {new_dev->function[i] = callbacks[i];}}return new_dev;
}

4. 实现方法函数

// 初始化硬件方法
void InitHardWareImpl(void) {printf("Hardware initialized\n");
}// 反初始化硬件方法
void InitDeHardWareImpl(void) {printf("Hardware deinitialized\n");
}// 唤醒设备方法
void WakeupImpl(struct OBJ_DEV_T* DevInst) {printf("Device %s woken up\n", DevInst->instance_name);
}// 休眠设备方法
void SleepImpl(struct OBJ_DEV_T* DevInst) {printf("Device %s put to sleep\n", DevInst->instance_name);
}// 运行指定函数方法
void RunImpl(struct OBJ_DEV_T* DevInst, const char *name, void* argument) {printf("Running function %s on device %s\n", name, DevInst->instance_name);// 在实际应用中,这里会根据名称查找并执行对应的回调函数if(strcmp(name, "LED_On") == 0) {LED_On(argument);} else if(strcmp(name, "LED_Off") == 0) {LED_Off(argument);} else if(strcmp(name, "LED_Blink") == 0) {LED_Blink(argument);}
}// 创建运行函数方法
void CreateRunImpl(struct OBJ_DEV_T* DevInst, const char *name, void (*fun)(void* argument)) {printf("Creating run function %s for device %s\n", name, DevInst->instance_name);// 在实际应用中,这里会将函数指针存储到回调函数数组中// 这里简化处理,只是打印信息
}

5. 初始化回调函数数组

// 初始化回调函数数组
void OBJ_Callback_init(run_t* callbacks) {// 初始化回调函数数组,这里简单设置为NULLfor(int i = 0; i < CALLBACKCOUNT; i++) {callbacks[i] = NULL;}
}

6. 主函数演示使用流程

int main() {printf("=== LED设备控制演示 ===\n\n");// 1. 初始化回调函数数组run_t callbacks[CALLBACKCOUNT];OBJ_Callback_init(callbacks);// 2. 创建设备实例printf("步骤1: 创建设备实例\n");struct OBJ_DEV_T* LED_Device = CreateOBJ_DEV("LEDDevice", callbacks);printf("创建了设备: %s\n\n", LED_Device->instance_name);// 3. 设置设备方法printf("步骤2: 设置设备方法\n");LED_Device->method.InitHardWare = InitHardWareImpl;LED_Device->method.InitDeHardWare = InitDeHardWareImpl;LED_Device->method.Wakup = WakeupImpl;LED_Device->method.Sleep = SleepImpl;LED_Device->method.Run = RunImpl;LED_Device->method.CreateRun = CreateRunImpl;printf("设备方法设置完成\n\n");// 4. 初始化硬件printf("步骤3: 初始化硬件\n");LED_Device->method.InitHardWare();LED_Device->is_initialized = 1;printf("\n");// 5. 创建设备运行函数printf("步骤4: 创建设备运行函数\n");LED_Device->method.CreateRun(LED_Device, "LED_On", LED_On);LED_Device->method.CreateRun(LED_Device, "LED_Off", LED_Off);LED_Device->method.CreateRun(LED_Device, "LED_Blink", LED_Blink);printf("\n");// 6. 运行设备函数printf("步骤5: 运行设备函数\n");int blink_times = 5;LED_Device->method.Run(LED_Device, "LED_On", NULL);LED_Device->method.Run(LED_Device, "LED_Blink", &blink_times);LED_Device->method.Run(LED_Device, "LED_Off", NULL);printf("\n");// 7. 休眠设备printf("步骤6: 休眠设备\n");LED_Device->method.Sleep(LED_Device);printf("\n");// 8. 唤醒设备printf("步骤7: 唤醒设备\n");LED_Device->method.Wakup(LED_Device);printf("\n");// 9. 反初始化硬件printf("步骤8: 反初始化硬件\n");LED_Device->method.InitDeHardWare();printf("\n");printf("=== 演示结束 ===\n");// 释放内存free(LED_Device);return 0;
}

在这里插入图片描述
在这里插入图片描述

http://www.dtcms.com/a/355240.html

相关文章:

  • 从用户视角出发:如何提升B端产品的操作效率?
  • 把 AI 塞进「智能水杯」——基于声学指纹的零样本水质检测杯
  • [p2p-Magnet] 队列与处理器 | DHT路由表
  • Chrome 插件开发实战:从入门到精通
  • 基于复旦微ZYNQ7015+VU3P 的双FMC 基带信号处理平台(国产率100%)
  • 基于复旦微RFVU3P FPGA 的基带信号处理板(100%国产率)
  • 水果目标检测[3]:计算机视觉中的深度学习用于监测苹果树生长和水果生产的综合综述
  • 配置 Gitlab 和 Elasticsearch/Zoekt 并使用 Docker Metadata 数据库、Camo 代理服务
  • 鸿蒙Harmony-从零开始构建类似于安卓GreenDao的ORM数据库(五)
  • QP原理讲解
  • 企业微信配置LangBot通信机器人
  • Javascript》》JS》》ES6》》总结
  • 企业招聘难题破解:主流AI面试工具实测对比
  • 【Linux知识】Linux 设置账号密码永不过期
  • Day15 (前端:JavaScript基础阶段)
  • 健永科技RFID技术在羊智能分群管理系统的使用案例
  • leetcode 3446. 按对角线进行矩阵排序 中等
  • 3446. 按对角线进行矩阵排序
  • 前端异常监控,性能监控,埋点,怎么做的
  • 响应式编程框架Reactor【1】
  • React 类生命周期 和 React Hooks 比对
  • 算力沸腾时代,如何保持“冷静”?国鑫液冷SY4108G-G4解锁AI服务器的“绿色空调”!
  • 第五章:Go运行时、内存管理与性能优化之性能分析与pprof工具
  • 配置windows下apache+PHP环境
  • 前端技术之---复制文本
  • docker安装kafka、zookeeper详细步骤
  • 【TEC045-KIT】基于复旦微 FMQL45T900 的全国产化 ARM 开发套件
  • COLMAP 和 SFM的关系是什么?
  • 微服务即时通信系统(十三)--- 项目部署
  • 第十七章 Java基础-常用API-System