0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C语言使用回调函数模拟委托与反射

STM32嵌入式开发 来源:STM32嵌入式开发 作者:STM32嵌入式开发 2022-03-14 10:19 次阅读

函数是C语言的核心概念。主调函数(caller)调用被调函数(callee)是一般的调用关系,如果被调函数(callee)参数包含函数指针,函数指针还可以形成多一层的调用关系,形成第三方函数的调用,专业术语称为回调(callback),通过函数指针参数调用的第三方函数称为回调函数。

回调可以让被调函数(这里是指用函数指针做函数参数的函数)的代码更加泛化或抽象,能够简单模拟其它编程语言的委托与反射语法。

1 简单模拟委托

//C语言简单模拟委托//需要用的指针函数。通过用指针函数作为地址接收函数地址,以达到委托其他函数实现某方法的目的。#include typedef void(* fun)(); //typedef 把void(*)()类型重命名为funvoid func(fun); // 被调函数void func_1(); // 回调函数1void func_2(); // 回调函数2 int main() // 主函数用做主调函数{ func(func_1); fun f = func_2; f(); func(func_1); func(func_2); getchar(); return 0;}void func(fun f) //fun f为地址,fun * f为f指向的地址的量或者其他{ printf("func "); if (f != NULL) { f(); }}void func_1(){ printf("func_1 ");}void func_2(){ printf("func_2 ");}/*funcfunc_1func_2funcfunc_1funcfunc_2*/

2 简单模拟反射

(1)简单模拟反射

高级语言的反射机制,简单来说,就是可以通过字符串型获取对应的类或者函数。下面,用C来简单模拟反射:

#include #include typedef void (*callback)(void); typedef struct { const char *name; callback fn;}callback_t; void f0();void f1(); callback_t callbacks[] = { {"cmd0", f0}, {"cmd1", f1},}; void f0() // 回调函数0{ printf("cmd0");} void f1() // 回调函数1{ printf("cmd1");} void do_callback(const char *name) { size_t i; for (i = 0; i < sizeof(callbacks) / sizeof(callbacks[0]); i++) { if (!strcmp(callbacks[i].name, name)) { callbacks[i].fn(); } }} int main(){ do_callback("cmd1"); getchar(); return 0;}

(2)利用自定义段

gcc支持通过使用 __ attribute __ ((section())),将函数、变量放到指定的数据段中。也就是说,可以让编译器帮我们完成上例中向数组添加成员的动作。

借助此机制,回调函数可以在任意文件声明,不需要修改其他文件。自定义段的起始和结束地址,可以通过变量 __ start_SECTIONNAME 和 __ stop_SECTIONNAME得到例如通过 __ attribute __ ((section("ss"))定义自定义段,其开始地址为 & __ start_ss,结束地址为 & __stop_ss。

// https://www.bejson.com/runcode/c920/#include #define SEC __attribute__((__section__("ss"), aligned(sizeof(void*)))) void func_1 (int a, int b){ printf("%s %d %d ", __func__, __LINE__, a+b); }void func_2 (int a, int b){ printf("%s %d %d ", __func__, __LINE__, a*b); } // 编译器会自动提供__start_ss,__stop_ss标志段ss的起止地址extern size_t __start_ss;extern size_t __stop_ss; typedef struct { void (*p)(int, int);} node_t; // 结构体变量a位于自定义段ssSEC node_t a = { .p = func_1, };SEC node_t b = { .p = func_2, };int main(int argc, char **argv){ int a = 3, b = 4; node_t *p; // 遍历段ss,执行node_t结构中的p指向的函数 for (p = (node_t *)&__start_ss; p < (node_t *)&__stop_ss;p++) { p->p(a, b); a+=1;b+=2; }}/*func_1 6 7func_2 10 24 */

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    180

    文章

    7534

    浏览量

    129180
  • 函数
    +关注

    关注

    3

    文章

    3911

    浏览量

    61368
  • 编译器
    +关注

    关注

    1

    文章

    1577

    浏览量

    48645

原文标题:C语言使用回调函数模拟委托与反射

文章出处:【微信号:c-stm32,微信公众号:STM32嵌入式开发】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    c语言函数函数体用什么符号括起来

    函数 是指将一组能完成一个功能或多个功能的语句放在一起的 代码结构 。 在 C语言程序 中,至少会包含一个函数,及主函数main()。本文将详细讲解关于
    的头像 发表于 11-24 15:52 325次阅读
    c<b class='flag-5'>语言</b>中<b class='flag-5'>函数</b>的<b class='flag-5'>函数</b>体用什么符号括起来

    c语言gets函数可以输入数字吗

    C语言中的gets函数是用来读取字符串的,而不是用来读取数字的。它会读取输入的字符直到遇到换行符或者文件结束符。因此,如果你尝试使用gets函数来读取数字,是无法准确获取数字本身的。 首先,让我们
    的头像 发表于 11-24 10:00 722次阅读

    c语言max函数在哪个库

    C语言的max函数并不属于标准C库,它通常是由程序员自己编写的一个宏定义。max函数用于比较两个数的大小,返回较大的数值。 为了提供更多详实的信息,下面将详细介绍C语言中max
    的头像 发表于 11-22 10:18 1573次阅读

    c语言max函数的使用方法

    C语言是一门广泛使用的编程语言,提供了许多内置的函数来执行各种任务。其中一个非常有用的函数是max函数,它用于比较两个值并返回较大的那个值。
    的头像 发表于 11-22 10:15 5582次阅读

    模拟光线的折射与全反射小程序

    使用LabVIEW模拟光线的折射与全反射
    发表于 11-16 15:56

    如何用Python来理解委托模式

    voice 类产生“狗吠 ” 声,这时候就可以采用 委托模式 。下面就用Python来理解这个设计模式。 Python里,在委托者类对象中,需要这么设计: 1. 重写__getattr__方法,使得委托者获得处理者的属性。 2
    的头像 发表于 11-02 15:30 296次阅读
    如何用Python来理解<b class='flag-5'>委托</b>模式

    怎么设计c语言的可变长参数函数

    怎么设计c语言的可变长参数函数
    发表于 10-27 07:10

    SCL语言编写的模拟量输入信号处理函数介绍

    今天这篇文章,我们在博途平台下用SCL语言编写一个模拟量输入信号处理的函数块,它可用于S7-1200/1500系列PLC。
    的头像 发表于 09-21 09:25 395次阅读
    SCL<b class='flag-5'>语言</b>编写的<b class='flag-5'>模拟</b>量输入信号处理<b class='flag-5'>函数</b>介绍

    为什么单片机中断函数会使用回函数实现?

    为什么单片机中断函数会使用回函数实现
    发表于 09-20 07:50

    第十一集 如何使用回函数? - 第1节

    单片机函数代码nginx
    充八万
    发布于 :2023年08月17日 15:38:34

    C语言函数的基本知识

    函数是C语言中的基本构建块之一,它允许我们将代码组织成可重用、模块化的单元。
    发表于 08-16 18:25 382次阅读

    C语言中指针函数函数指针的概念及应用示例

    在C语言中,指针函数函数指针是强大且常用的工具。它们允许我们以更灵活的方式处理函数和数据,进而扩展程序的功能。
    发表于 08-16 16:14 348次阅读

    在nuclei studio中编译遇到的两个问题,计数模块显示未声明和如何在c工程中添加硬件描述语言

    core_feature_base.h,却可以在编译的时候使用core_feature_base.h声明计数模函数 2.使用nice接口的Verilog文件 可以与c语言软件程序一
    发表于 08-16 07:06

    C语言使用回函数模拟委托反射

    函数是C语言的核心概念。主调函数(caller)调用被调函数(callee)是一般的调用关系,如果被调函数(callee)参数包含
    发表于 08-03 16:12 343次阅读

    在哪里可以找到在s32k中配置回函数的例子呢?

    嗨社区我需要测量 ptd0、pte11、ptd1 的频率,然后我尝试配置所有通道 iam 配置一个通道,但我配置了输入,它必须调用回函数它没有调用任何回
    发表于 06-08 07:35