库的创建与使用

什么是库

库是一组预编译好的函数集合,这些函数都是按照可重用得原则编写。在库中的函数是互相关联的,通过这些函数组合可以实现相应功能,如屏幕处理函数(curses和ncurses),数据库访问例程(dbm库)。
在Linux中标准的库文件一般存放在/lib和/usr/lib目录中。c语言编译器(确切的说是链接程序)需要知道要搜索哪些库文件,默认情况下它只搜索标准的c语言库。仅仅把库文件放在标准目录就希望c语言编译器gcc找到他们是不够的,库文件的命名必须遵循一定的规范并且在命令行中明确指定。
gcc -o hello hello.c /usr/lib/libm.a

  • 库文件的名字总是以lib开头,随后指明这是什么库,如(c代表c库,m是数学库)。
  • 文件后缀.a代表的是传统的静态库,.so代表的是动态库。函数库通常以静态库和动态库两种格式存在,可以通过完整的路径名或者-l标志来告诉gcc需要搜索的库文件,如 gcc -o hello hello.c /usr/lib/libm.a 命令在编译hello.c文件时不仅要搜索标准的c库,还需要搜索/usr/lib/libm.a 路径下的数学库解决函数引用的问题,gcc hello.c -lm -o hello 命令是利用标志-l的搜索方法,-l标志与路径搜索的不同是在静态库和动态库都有的时候优先会选择动态库。
  • 用-L可以指定搜索的路径,如(gcc hello.c -lm -L ./ -o hello )是在编译时优先在当前目录下搜索名为m的库。

库的分类

程序函数库可分为3种类型:静态函数库(static libraries)、共享函数库(shared libraries)、动态加载函数库(dynamically loaded libraries):
1、静态函数库,是在程序执行前就加入到目标程序中去了 ;
2、动态函数库同共享函数库是一个东西(在linux上叫共享对象库, 文件后缀是.so ,windows上叫动态加载函数库, 文件后缀是.dll)

静态库、动态库优缺点

静态库:

优点:

1.静态库被打包到应用程序中加载速度快
2.发布程序无需提供静态库,因为已经在app中,移植方便

缺点:

1.链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝。当同时运行多个应用程序并且它们都使用同一个静态库中的函数时,内存中就会有同一个函数的多份副本,而且程序文件自身也有多份同样的副本。这会消耗大量宝贵的内存和磁盘空间。
2.更新、部署、发布麻烦。
库的创建与使用

动态库:

优点:

1.链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序可以共用,节省内存。
2.程序升级简单,因为app里面没有库的源代码,升级之后只要库的名字不变,函数名以及参数不变,只是实现做了优化,就能加载成功。

缺点:

1.加载速度比静态库慢
2.发布程序需要提供依赖的动态库
库的创建与使用

库的创建

静态库
  1. 先gcc编译 加-c生成 .o文件。(gcc print.c -c )xxx.c 生成xxx.o
  2. ar rcs libprint.a print.o xxx.o 生成libxxx.a。 ar程序是将若干个单独的文件归并到一个大的文件中以创建归档文件或集合。当然,ar程序也可以创建任何类型文件的归档文件。
使用

gcc main.c -lprint -L ./ -o xxx
直接执行xxx程序,从当前路径搜索print库并加载。

动态库
  1. gcc -shared -fpic print.c -o libprint.so
  2. -shared 指定生成动态库。
    -fpic 标准,fPIC 选项作用于编译阶段,在生成目标文件时就得使用该选项,以生成位置无关的代码。
使用
  1. gcc main.c -lprint -L ./ -o xxxx
  2. 直接执行xxx文件会出错,因为程序执行中需要动态的加载函数库,依然会去/usr/lib 目录下去搜索,可以配置环境变量。
  3. LD_LIBRARY_PATH=“路径”,但这只是暂时的,更好的办法是写入shell文件,再执行shell文件。