简单说说C语言标准库和嵌入式C语言标准库

 

目录

例子说明C语言标准库和嵌入式C语言标准库是有区别的

一个小问题?

C语言中实现多态的方法

定义虚函数

函数指针来模拟

回调函数实现

总结


 

例子说明C语言标准库和嵌入式C语言标准库是有区别的

我们从一个重定向的例子引入,一是在Linux GCC环境下,另一个是使用HAL库开发stm32串口应用。

在Linux GCC环境下,当我们要将标准输出(printf)重定向到其他文件的时候,是先将标准输入的文件描述符关闭,即关闭0号文件描述符,打开需要重定向的文件,进程就会将0号文件描述符分配给这个文件,标准输出默认会向0号文件描述符写内容。

使用HAL库开发stm32串口应用的时候,当我们想要通过调用标准输出向串口发送消息的时候,需要重写fputc弱函数,因为在嵌入式C标准库中,标准输出中最后是调用了fputc函数,一个字符一个字符的发送的。

从这个地方,我们就能看的出来,由ISO C标准定义的C语言标准库与嵌入式C标准库的不同了,多在文件系统和操作系统的系统调用的方面有所不同。 在MicroLIB中,fputc函数的默认历程是什么都不做,需要用户重写,HAL库在默认历程中调用用户重写后的fputc函数。

一个小问题?

这里又有一个问题?C语言是如何做到重写和多态的呢?我们知道在C++中,当我们利用面向对象的多态特性的时候,派生类中重写基类中定义的虚函数,使用指向派生类的基类指针调用虚函数,在运行时会发生动态绑定(动态多态)。

C语言中实现多态的方法

下面就介绍几个C语言中实现多态的方法

定义虚函数

MicroLIB 库中的实现方法,定义_weak弱函数。他的原理是:在编译链接的时候,使用用户重写的fputc函数的地址,代替弱函数int fputc(int /ch/, FILE /fp/)函数的地址,如果用户没用重写,就使用弱函数_weak int fputc(int /ch/, FILE /fp/)函数的地址(这时的编译器对每个函数生成符号表目的时候,还会标记强弱属性,链接器最终会选择强属性的函数或者变量的地址)。

函数指针来模拟

使用函数指针来模拟实现多态

当派生类中的第一个成员基类的指针的时候,第一个成员的地址就是基类的地址。当我们使用基类指针指向派生类的时候,只要在调用派生类中的方法的时候,将他强转之后就可以了。

回调函数实现

最后说一个比较流氓的方法:使用回调函数实现多态。

我们回顾一下多态的本质,同一个接口,不同的上下文中执行不同的实现。

回调函数是将函数指针作为参数,传递给另一个实现多态的函数,这个函数在合适的使用通过函数指针调用函数。这样也就变相的实现了多态。

这样的实现方式呢,通常是在操作系统内核中,如Linux操作系统内核,嵌入式系统,如HAL库,库设计中,如thread库封装LWP轻量级进程...

总结

C语言标准库在大体上可以分为两类,一类是由ISO C标准定义的C语言标准库,另一类是嵌入式C标准库,这两类不是完全不同的两个库,而是同一标准的不同实现。

C语言标准库,在PC/服务器等环境中,标准库的实现依赖于操作系统(如Linux的glibc、Windows的MSVCRT)。功能完整,但代码体积较大,依赖操作系统。

嵌入式C标准库是对嵌入式系统资源受限的特性(内存小、无操作系统),对标准库进行精简或优化后的实现。

比如:

MicroLIB(ARM Keil专用):高度精简,代码体积小,直接调用用户实现的底层函数(如fputc)。

newlib(GCC常用):功能较完整,但允许用户重定向底层接口(如_write)。

移除对操作系统的依赖(如文件系统、多线程)。

保留标准接口(如printf),但要求用户自行实现硬件相关的底层函数(如字符发送)。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
OSZAR »