对于C这种面向过程的语言来说,使用的函数库,
而对于java这种面向对象的语言来说,使用的则是类库

参考:
操作系统 - 静态库和动态库,进程间通信 之 共享内存
C高级 - 静态链接 与 动态链接


一、代码复用的方式

函数代码的复用方式有如下几种:

  • 以源码形式复用
  • .o文件复用
  • 以库形式复用

1. 以源码形式复用

如何复用

在自己的程序中,需要调用到什么函数,就将函数源码所在的.c.h拷贝到自己C工程中,
然后和自己的程序的.c.h一起编译,然后得到可执行程序

对于编译器来说,不管是自己写的代码,还是复用的源码,都是一样的,并没有区别,
只不过复用的源码不一定是我们自己写的

以源码形式复用情况并不少见,以源码形式复用时,我们可以将源码直接称为“源码库”,
当然源码有源码的好处,好处就是,你可以通过源码了解代码的具体实现,但是源码的缺点也是明显的

使用源码有三个缺点:

  • (1)缺点1:“源码可见”不利于版权保护
  • (2)缺点2:我们自己要清楚,我们要使用的函数在哪个.c中,
    但是如果源码中.c.h非常多的话,这就有些麻烦了
  • (3)缺点3:编译c源码很耗费时间
    如果程序的代码量非常庞大的话,是非常耗费编译时间的,
    本来当一个程序写大之后,就已经要耗费不少的编译时间了,
    如果再加入大量的库源码在里面,这将会更加的拉长编译时间

正是因为以上原因,所以源码库虽然不少见,但是也并不多见,
比如stm32单片机的标准外设库和HAL外设库,就是以源码形式提供的,但凡提供源码,必然是开源的


2. 以二进制.o文件复用

如何复用

事先将要被复用的.c全部编译为对应的.o

你要调用什么函数,就将这个函数所在的.o复制到自己的工程中,
然后与自己程序的.o链接到一起,就得到了可执行程序

优点:

  • (1).o为二进制文件,文本编辑器是无法正常显示二进制文件的,
    打开后为一堆的乱码,提供.o的话,可以有效的避免了源码外泄的问题
  • (2)要复用的源码,事先早就被编译为了.o,只需要链接即可,有效的节省了编译时间

缺点

当要复用的.o非常多时,比如有几十个、甚至几百个时,
要记住那些函数在那些.o中的话,其实是很困难的事情

基于这样的原因,大家就想着能不能自动识别呢,比如我在程序中调用到了什么函数,
就自动去识别这个函数在哪个或者那几个.o中,然后自动去链接这些.o,于是就有了真正意义上的“函数库”

真正的“库”其实就是就是将.o进行打包,做成库文件,
链接库时,库会自动识别我们程序中调用的函数在哪些.o中,然后自动找到那些.o,然连接到我们的程序中


3. 库的原理

原理很简单,先将要复用的源码.c编译为对应的.o,然后再将所有的.o打包做成“库”文件

使用时,直接链接“库文件”即可,在程序中调用了某个函数,
链接库文件时会自动帮我搜索这个函数在库中的哪些.o中,然后就链接库中这些.o

做成真正的库文件有如下好处:

  • (1)不需要公开源码,维护了版权
  • (2)不需要浪费额外的编译时间,因为事先就编译好了,只需要链接即可
  • (3)也不需要人为的挑选.o,链接库时会自动的搜素。

库分为两种,静态库 和 动态库。静态库和动态库文件的尾缀,与编译器和操作系统都有关。

静态库

总的来说,静态库的尾缀是由平台来决定的

  • Windows平台:静态库的结尾为.lib
  • Linux平台:静态库的结尾为.a

但实际上静态库文件是以.a结尾还是.lib结尾,与编译器也有关,
比如gcc编译器,不管编译得到静态库是运行在Windows上还是运行在Linux上,
使用gcc做出的静态库文件都是以.a结尾的

动态库

动态库名字的尾缀,基本上只与平台有关,

  • Windows平台:动态库的结尾为.dll
  • Linux平台:动态库的结尾为.so