概述
函数库其实就是函数,只不过是系统所调用的函数。这样说吧,我写了一个软件,所有的功能都需要我自己完成吗?其实是不需要的,因为很多功能是别人已经写好的,我只需要拿来用就好了。这些有独立功能并且可以被其他程序调用的程序是函数。
函数库分类
当其他程序调用函数时,根据是否把函数直接整合到程序中而分为静态函数和动态函数。我们分别看看这两种函数的优缺点。
静态函数库
函数库文件一般以"*.a"扩展名结尾,这种函数库在被程序调用时会被直接整合到程序当中。
优点:程序执行时,不需要在调用外部数据,可以直接执行。
缺点:因为把所有内容都整合到程序中,所以编译文件会比较大,升级比较困难,需要把整个程序重新编译。
动态函数库
函数库文件通常以"*.so"扩展名结尾,这种函数库在被程序调用时,并没有直接整合到程序当中,当程序需要用到函数库的功能时,再去读取函数库,在程序中只保存了函数库的指向,如图 1 所示。
优点:因为没有把整个函数库整合到程序中,所以文件较小,升级方便,不需要把整个程序重新编译,只需要重新编译安装函数库就好。
缺点:程序在执行时需要调用外部函数,如果这时函数出现问题,或指向位置不正确,那么程序将不能正确执行。
目前 Linux 中的大多数函数库是动态函数库,主要是因为升级方便;但是函数的存放位置非常重要,而且不能更改。目前被系统程序调用的函数主要存放在"/usr/lib"和"/lib"中,而 Linux 内核所调用的函数库主要存放在"/lib/modules"中。
安装函数库
那么,系统中的可执行程序到底调用了哪些函数库呢?可以査询到吗?当然可以,命令如下:
[root@localhost ~]# ldd -v 可执行文件名
选项:-v: 显示详细版本信息
比如,査看一下 ls 命令调用了哪些函数库,命令如下:
[root@localhost ~]# ldd /bin/ls linux-gate.so.1 => (0x00d56000) libselinux.so.1 =>/lib/libselinux.so.1 (0x00cc8000) librt.so.1 =>/lib/librt.so.1 (0x00cb8000) libcap.so.2 => /lib/libcap.so.2 (0x00160000) libacl.so.1 => /lib/libacl.so.1 (0x00140000) libc.so.6 => /lib/libc.so.6 (0x00ab8000) libdl.so.2 => /lib/libdl.so.2 (0x00ab0000) /lib/ld-linux.so.2 (0x00a88000) libpthread.so.0 => /lib/libpthread.so.0 (0x00c50000) libattr.so.1 =>/lib/libattr.so.1 (0x00158000)
新安装了一个函数库,如果是正常安装的,则是不需要手工调整函数库的。如果没有安装正确只要把函数库放入指定位置,一般放在"/usr/lib"或"/lib"中,然后把函数库所在目录写入"/etc/ld.so.conf"文件中。注意是写入函数库所在目录,而不是写入函数库的文件名。比如:
#把函数库复制到/usr/lib/目录中 [root@localhost ~]# cp *.so /usr/lib/ #修改函数库配置文件 [root@localhost ~]# vi /etc/ld.so.conf #写入函数库所在目录(其实/usr/lib/目录默认已经被识别) include ld.so.conf.d/*.conf /usr/lib
接着使用 ldconfig 命令重新读取 /etc/ld.so.conf 文件,把新函数库读入缓存即可。命令如下:
#从/etc/ld.so.conf文件中把函数库读入缓存 [root@localhost ~]# ldconfig #列出系统缓存中所有识别的函数库 [root@localhost ~]# ldconfig -p