嵌入式多态原理详解
时间:2023-06-19 11:17:54来源:CSDN-HiveIOE

引言


(资料图片仅供参考)

在我们的嵌入式C 开发中经常会面对这样的一类需求:因为对接的设备支持的协议不同,自身的设备需要兼容这些协议,因此需要业务支持不同的协议解析方式。

比如有的协议用 tlv 的数据格式,有的用 xml 的格式,有些又用 json 这样的格式,面对如此多差异化的需求,我们该如何解决呢?

一种常见的做法是将协议解析和逻辑实现做到一起,每种协议对应一套代码,这种实现方式简单,没有什么设计可言,就是撸代码。

但是每当对接一种新的协议就要从头开发,这种重复造轮子的方式非常初级,代码的可扩展性也非常差,有没有一种更高级一点的方法呢?

答案是有的,也就是我们本文要讲的嵌入式多态。

嵌入式多态原理

我们首先审视一下上面的需求,上述需求的特点是协议是有多种的数据承载格式(tlv/json/xml),需要针对不同的协议做解析,但是解析完成后的数据处理,也就是业务逻辑的部分却可以保持不变。

因此我们完全可以使用一种模型将这两者分离开来,将易变的协议解析部分单独作为一个模块,将不易变的业务逻辑作为一个模块。

协议解析模块主要负责生成数据,而业务逻辑模块就主要对数据进行处理,中间链接这两者的模型,我们暂且称之为数据分发模型,负责将协议解析出的数据传给业务逻辑部分。

这样一来协议解析模块就可以在自己内部做任何变化,可以对不同格式的协议进行解析,而这对于业务逻辑来说都是不感知的,代码的扩展性更佳。

要想达到这种良好的可扩展性,我们引入了一个负责数据分发的模型,这个模型要怎么实现呢?

我们看到协议解析其实是有多种实现方式,而业务逻辑可以看作只有一种实现方式,这就是一种多对一的方式。

在数据分发模型中,负责将多种协议解析方式收敛成一种,我们想一下C语言中哪种方式可以实现这种多对一的收敛呢?没错,就是函数指针。

这是指针的一种非常高级的应用,它可以将函数的框架抽象出来,用指针的方式进行定义,我们知道指针可以初始化指向不同的地址,那函数指针就可以被指向多个不同的函数。

当我们调用函数指针时,就可以动态地切换到不同的函数实现上。想一下,虽然协议解析的方式不同,但是最终业务逻辑需要的数据是固定的,因此完全可以将函数的参数搞成一样的结构。

在面向对象的编程语言中,这种实现方式称之为多态,同一个接口(抽象级,没有具体实现)可以支持不同的具体实现。在我们嵌入式C开发中需要自己写这种多态的接口,但是也不难,笔者将一个模板写在了下一节中,读者可以参照这种写法,灵活修改。

嵌入式多态伪代码实现模板

定义数据分发的模型,抽象接口

1)伪代码

/*回调的函数钩子*/typedefint(*hook_func)(void*,int,void*);typedefstruct{/*初始化接口,定义诸如内存之类的问题*/void(*init)(void);/*注册服务对应的处理函数,如协议解析后的业务逻辑处理映射*/int(*register)(inttype,hook_funcfunc);/*将数据分发到对应的服务*/int(*distribute)(void*input,intlen,void*ret);}demo_param_s;

2)代码解析

在这个结构体中,我们定义了三个函数指针,分别是:

初始化接口,用来初始化内存之类,这个内存可以用来存储我们提供的服务类型和回调函数;

注册服务处理函数,主要用来建立服务类型和回调函数的映射,在我们的案例中主要将协议解析后,需要使用哪种业务逻辑处理,建立这样的一个模型;

数据分发服务,主要将协议解析后的数据作为参数,在服务映射表中找到对应的回调函数,然后进行回调。

如下图所示,可以非常详细的描述这个过程。

数据分发模型的初始化接口

1)伪代码

demo_param_s*g_demo_param=NULL;voiddemo_init(constdemo_param_s*param){g_demo_param=param;return;}

2)代码解析

上面的这部分代码非常简单,首先是定义了一个全局变量,这个全局编码是数据分发模型的类型,用来指向一个数据分发模型的具体实现,初始时,可以让这个全局变量指向空。

接下来,就是定义了一个初始化接口,这个接口是来初始化我们定义的这个全局变量的,你会看到这个全局变量指向了一个输入进来的参数,而这个参数就是数据分发模型中各个函数指针的具体实现函数,你将在下一节中看到。

每个函数指针的具体实现

1)伪代码

voidinit_impl(void);intregister_impl(inttype,hook_funcfunc);intdistribute_impl(void*input,intlen,void*ret);demo_param_sdemo_param={.init=init_impl,.register=register_impl,.distribute=distribute_impl};demo_init(&demo_param);

2)代码解析

这部分的伪代码主要是对3个函数指针实现,并进行初始化。

首先是三个具体的实现函数被声明和定义,第一个初始化函数,就是 malloc 出内存;第二个函数,建立服务和业务处理函数的映射关系;第三个函数,在需要某种服务时,通过查询第二个函数建立的映射表,回调具体的业务;

其次就是定义了一个数据分发模型的局部变量,然后初始化其中的每个函数指针;

最后调用我们在前面定义的数据分发初始化接口,将上面定义的局部变量的值传入,使其可以全局访问,在后面我们就可以直接用全局变量 g_demo_param 加上其中的参数的方式调用每个接口。

通过抽象接口调用注册和分发功能

1)伪代码

//分发for(i=0;i
//注册inttype=0;intlogic_func(void*input,intlen,void*ret);ret=g_demo_param.register(type,logic_func);

2)代码解析

上面就是我们的注册和分发的接口,其中注册的部分是在业务逻辑中实现的,分发的部分代码是在协议解析的部分实现的。

需要特别注意这个实现规则,因为只有这样才能达到业务逻辑和协议解析的分离,协议解析只依赖我们的数据分发模型,业务逻辑也只依赖我们的数据分发模型,这两者之间互不依赖,可以独立的编译或者打包。

首先我们看注册,有类型和具体函数实现,我们可以使用 g_demo_param.register 去创建两者的映射关系,将其保存在内存中。

然后当我们解析完协议,就来到我们的分发部分,当我们的类型在内存映射表中有存储时,就可以使用g_demo_param.distribute 实现分发,调用我们的业务逻辑代码。

小结

随着嵌入式软件变得越来越复杂,架构问题也变得越来越突出,市场上我们最多见的是对互联网这类架构的介绍,鲜有专门针对嵌入式软件的架构分析。本文通过一个案例浅谈了嵌入式多态的实现方式,目的是帮助读者在设计开发相关的场景时能够拿来借鉴,使自己的代码具有更好地扩展性。

审核编辑:汤梓红

标签:

生活指南
  • 仲景食品:6月16日融资买入182.93万元,融资融券余额6387.83万元-全球速读

    6月16日,仲景食品(300908)融资买入182 93万元,融资偿还243 7万元,

  • 稳经济 促发展 强信心|走访问需办实事 精准服务促发展-今日热讯

    走访问需办实事,精准服务促发展。在深入推进“万人助万企”活动的进程

  • 克隆是什么工程 克隆工程是不是生物工程|全球快看点

    基因克隆属于基因工程,克隆羊属于细胞工程。至于遗传工程,包括广义和

  • 吹灭别人的灯,不会让自己更加光明!欧洲光伏展,以合作向未来! 全球报资讯

    吹灭别人的灯,并不会让自己更加光明!这个朴素的道理,在2023欧洲国际

  • 上交所上市委:金龙股份IPO将于6月26日上会 全球关注

    上证报中国证券网讯据上交所上市委6月16日消息,上海证券交易所上市审

  • 世界最资讯丨*ST华仪:聘任曾神贻为公司董事会秘书

    *ST华仪(SH600290,收盘价:1 38元)6月16日晚间发布公告称,华仪电气

  • 优巨新材新增产能或难消化,近半募资为补流,外销数据前后不一_天天观热点

    文:权衡财经iqhcj研究员李力 编:许辉 6月13日,金发科技公告第一季度

  • 多平台“618”迎“开门红” 当前焦点

    原标题:多平台“618”迎“开门红”(主题)已扩展为从零售到餐饮全方

  • 2023广东肇庆市端州区三榕工业园管理委员会考试录用公务员拟录用人员公示

    根据公务员考试录用有关规定,通过笔试、面试、体检、考察等程序,同志

  • 世界聚焦:五粮液加码消费活动,全面迎接端午消费旺季

    四川经济网讯(记者杨波侯云春)白酒市场表现作为中国消费市场的“晴雨

  • 财务核算、内控等三方面违规,圆通速递被责令改正

    6月15日,大连证监局发布《关于对圆通速递股份有限公司采取责令改正措

  • 天天日报丨globe 开通流量_globe开通流量套餐

    1、如果您使用的是中国联通的后付费手机号码,国际漫游至菲律宾globe网

  • 2023海口天空之山端午节可以去吗?|世界热点

    海口天空之山端午节端午节可以去,建议下午前往,白天温度较高,要做好

  • “2023上海中国画作品展”在长宁启幕 天天快看点

    由上海市美术家协会、上海中国画院主办的“2023上海中国画作品展”日前

  • 什么药膏祛痘印效果最好?3款男士祛痘护肤品,女生通用!

    什么药膏祛痘印效果最好?那小编来发表一下自己对祛痘印的看法吧。靠谱

  • 如何使用精华霜? 世界短讯

    精华霜是近年来越来越受欢迎的护肤产品。它含有高浓度的营养成分,可以

  • 民生
    • 某个人_关于某个人概略

    • 环球要闻:全国首个4.9GHz频段5G低空全域覆盖专网落地无锡

    • 环球微速讯:中央商场(600280)6月16日主力资金净卖出609.39万元

    • 开花后怎么养才能继续开花 开花后如何养才能继续开花_今头条