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

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

3天内不再提示

C语言简单模拟委托与简单模拟反射

GReq_mcu168 来源:小智雅汇 作者:小智雅汇 2022-03-09 17:17 次阅读

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

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

1、简单模拟委托

//C语言简单模拟委托
//需要用的指针函数。通过用指针函数作为地址接收函数地址,以达到委托其他函数实现某方法的目的。
#include
typedefvoid(*fun)();//typedef把void(*)()类型重命名为fun
voidfunc(fun);//被调函数
voidfunc_1();//回调函数1
voidfunc_2();//回调函数2

intmain()//主函数用做主调函数
{
func(func_1);
funf=func_2;
f();
func(func_1);
func(func_2);
getchar();
return0;
}
voidfunc(funf)//funf为地址,fun*f为f指向的地址的量或者其他
{
printf("func
");
if(f!=NULL)
{
f();
}
}
voidfunc_1()
{
printf("func_1
");
}
voidfunc_2()
{
printf("func_2
");
}
/*
func
func_1
func_2
func
func_1
func
func_2
*/

2、简单模拟反射

(1)简单模拟反射

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

#include
#include

typedefvoid(*callback)(void);

typedefstruct{
constchar*name;
callbackfn;
}callback_t;

voidf0();
voidf1();

callback_tcallbacks[]={
{"cmd0",f0},
{"cmd1",f1},
};

voidf0()//回调函数0
{
printf("cmd0");
}

voidf1()//回调函数1
{
printf("cmd1");
}

voiddo_callback(constchar*name)
{
size_ti;
for(i=0;i< sizeof(callbacks)/sizeof(callbacks[0]);i++){
if(!strcmp(callbacks[i].name,name)){
callbacks[i].fn();
}
}
}

intmain()
{
do_callback("cmd1");
getchar();
return0;
}

(2)利用自定义段

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

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

//https://www.bejson.com/runcode/c920/
#include
#defineSEC__attribute__((__section__("ss"),aligned(sizeof(void*))))

voidfunc_1(inta,intb)
{
printf("%s%d%d
",__func__,__LINE__,a+b);
}
voidfunc_2(inta,intb)
{
printf("%s%d%d
",__func__,__LINE__,a*b);
}

//编译器会自动提供__start_ss,__stop_ss标志段ss的起止地址
externsize_t__start_ss;
externsize_t__stop_ss;

typedefstruct{
void(*p)(int,int);
}node_t;

//结构体变量a位于自定义段ss
SECnode_ta={
.p=func_1,
};
SECnode_tb={
.p=func_2,
};
intmain(intargc,char**argv)
{
inta=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_167
func_21024

*/

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

文章出处:【微信公众号:硬件攻城狮】欢迎添加关注!文章转载请注明出处。

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

    关注

    11

    文章

    1398

    浏览量

    31477
  • C语言
    +关注

    关注

    180

    文章

    7534

    浏览量

    128826
  • 函数
    +关注

    关注

    3

    文章

    3904

    浏览量

    61310

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

文章出处:【微信号:mcu168,微信公众号:硬件攻城狮】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    简单交通灯并简单模拟车辆运行方向

    一个简单的交通灯,并用布尔数组模拟车辆运行方向。新手学习,请多多指教,努力改进。
    发表于 04-27 13:31

    求各种简单模拟电路图

    求各种简单模拟电路图
    发表于 04-07 22:16

    单模光纤-你应该选择什么样的?

    的多样性决定的。本文不仅仅涉及ITU-T和IEC的术语,也提及了简单的ITU-T G.65X。总体上有19种不同的单模光纤,它们的型号是由ITU-T定义的,这里将介绍一下单模光纤的种类。 每种类型的
    发表于 08-24 11:39

    DigiPCBA 库迁移系列 - 简单模

    简单界面模式和高级模式两种模式,文中介绍了四种方式来让您以简单模式访问迁移器。库迁移器的简单模式会根据其对源库和连接的工作区的分析,软件自己在后台会经过一系列的处理,预先自动选择迁移过程的所有方面,然后
    发表于 07-08 09:56

    LOG100的简单模式对数放大电路

    LOG100的简单模式对数放大电路 如图所示为LOG100的简单模式对数放大电路。信号输入电流I1、I2经过LOG100变换为对数输出VOUT=K·LOG(I1/I2)。从
    发表于 05-15 23:06 4043次阅读
    LOG100的<b class='flag-5'>简单模</b>式对数放大电路

    SIMULINK简单模型的建立及模型特点

    SIMULINK简单模型的建立及模型特点1、简单模型的建立    exp5_1.mdl(1)建立模型窗口(2)将功能模块由模块库窗口复制到模型窗口(3)对模块进
    发表于 06-19 12:48 2672次阅读

    S7-200简单模拟量编程程序

    西门子S7-200简单模拟量编程范例,西门子S7-200简单模拟量编程范例,TITLE=//子程序1:数据采集部份
    发表于 06-21 12:02 9750次阅读

    简单模拟控制的单相VIENNA整流器研究

    针对单相单开关三电平(VIENNA)整流器提出了新的简单模拟控制方案。该方案以单周期控制技术为基础,结构简单,无需R-S 触发器,在实现较高输入功率因数的同时,仅用单个电压环即
    发表于 09-22 16:30 61次下载
    <b class='flag-5'>简单模拟</b>控制的单相VIENNA整流器研究

    四种方式来让您以简单模式访问迁移器

    在《库迁移系列 - 前言》中,主要介绍了什么是库迁移器。DigiPCBA专用的库迁移器界面会自动分析您所选择的本地库并将它们迁移到您登录的工作区,实现一键式解决方案。库迁移器可以提供极简的简单界面模式和高级模式两种模式,文中介绍了四种方式来让您以简单模式访问迁移器。
    的头像 发表于 08-05 10:05 696次阅读

    单模和多模光纤中继器怎么选?

    单模光纤和多模光纤各有什么特点? 我们在选购CAN转光纤中继器时,经常不知道是旋转单模类型的还是多模类型的。 下面,我们简单了解下它们的特点,看看都有哪些不同: 单模
    的头像 发表于 05-29 12:04 458次阅读

    单模双纤和单模单纤的区别 单模单纤和双纤哪个好 效果一样吗

    单模双纤和单模单纤的区别 单模单纤和双纤哪个好 单纤和双纤效果一样吗  单模双纤和单模单纤是光纤通信领域中常用的概念。它们指的是在一对光纤中
    的头像 发表于 12-07 10:09 7149次阅读

    单模单纤与单模双纤的区别

    单模单纤与单模双纤的区别  单模单纤(single mode single fiber,SMF)和单模双纤(single mode dual fiber,SMDF)是光纤通信中常见的两
    的头像 发表于 12-08 10:41 2343次阅读

    单模单纤和单模双纤有什么区别

    单模单纤和单模双纤是光纤传输中两种常见的模式。单模指的是一种传输光信号的模式,单纤和双纤指的是光纤中的纤芯数量。下面将详细介绍单模单纤和单模
    的头像 发表于 12-20 14:40 2630次阅读

    单模光纤和多模光纤有什么区别?单模、多模能混合使用吗?

    单模光纤和多模光纤有什么区别?单模、多模能混合使用吗? 单模光纤和多模光纤是两种主要用于传输光信号的光纤。它们在传输特性、传输距离以及传输带宽等方面存在显著的区别。本文将详细介绍单模
    的头像 发表于 01-04 15:40 602次阅读

    单模光纤和多模光纤的型号区别是什么

    。纤维芯是光信号的主要传输介质,而包层则用于保护纤维芯并提供反射光信号的内部反射。 模式结构 单模光纤和多模光纤的最主要区别在于它们的纤维芯的尺寸和传输模式。 单模光纤:
    的头像 发表于 04-09 17:30 198次阅读