本帖最后由 sedatefire 于 2018-11-17 14:11 编辑
本文想展开一个比较偏向系统架构的问题:C文件可移植性实现,它本质上是一个接口设计问题。
我尝试展现这个思考过程,并希望得到大家的共鸣和修补。
一个c文件封装了很多实现细节,必然对应一个h文件,用于开放你的接口。
请问,开放哪些接口是合理的?
从"软件算法是围绕数据展开“”的朴素概念出发,基本上会有如下接口:
1. 初始化init,必须的。
2. 写入类的-------数据传入
3. 读取类的------数据传出,状态读取
4. 控制类的------变更内部控制参数
5. 事件传入触发执行的-----周期调用、中断事件传入等。
这些都是提供给用户层的接口,以上接口实现越少越好,每样一个是最理想的情况。
我尤其不建议
1. 开放extern全局变量
2. 开放复杂的复合结构体
这些增加了两个模块 变量名 + 结构体名称 耦合,最容易出现问题。
以上,是c文件提供给 “用户--函数调用人”的表层考虑。
但可移植性最难的地方,在于该c文件依赖了谁,换句话说。
1. 它引用多少个外部全局变量
2. 它引用了多少个外部结构体
3. 它调用了多少个外部函数,它们没在同文件内定义。
1和2的依赖,实际上就是其他h文件设计不合理的后果。
所以,
可移植性原则一:h文件里面尽可能只有API,API的参数设计尽可能只有基本数据类型。
然后再来讨论api接口名称的依赖,我们如何控制它。
外部的api名称体现在哪里? 在别的h文件里面。
所以直接可以推导出
可移植性原则二:控制c文件里面include的h文件个数。
可移植性原则三:控制每个h文件里面的api个数。
最后,如果这个c文件本身对外依赖的API小于3个,隶属于同一个h文件,可以引入callback策略,在初始化的时候传入这些api的函数指针。
如此,你的c文件就是一个 “纯算法、可移植文件”。
因为如果一个c文件,只依赖c库接口h文件,换MCU、换编译器,都是很轻松的事情。
注意:大小端转换使用移位写法。
|