静动态链接库的生成和使用

生成和使用静态链接库

静态库是obj文件的一个集合,通常静态库已“.a”为后缀,静态库由程序ar生成。
静态库的优点:

  1. 可以在不用重新编译程序库代码的情况下,进行程序的重新链接,这种方法节省了编译过程的时间,但是由于现在系统的强大编译的时间已经不是问题;
  2. 开发者可以提供库文件给使用的人员,不用开发源代码。
  3. 理论上,静态链接库的执行速度比共享库和动态链接库要快1%~5%。
生成静态链接库

生成静态库或者将一个obj文件加到已经存在的静态库的命令为“ar 库文件 obj文件1 obj文件2”。工具ar的-r选项,可以创建库,并把目标文件插入到指定库中。例如:将string.o打包为库文件libstr.a的命令为:

$ar –rcs libstr.a string.o
使用静态链接库

GCC链接时使用库函数和一版的obj文件的形式是一致的,例如:对main.c进行链接的时候,需要使用之前已经编号的静态链接库libstr.a,命令格式如下:

$gcc –o test main.c libstr.a

也可以使用命令“-l 库名”进行,库名是不包括函数库和扩展名的字符串。例如:编译main.c链接金泰库libstr.a的命令可以修改为:

$gcc –o test test.c –lstr    //在系统默认的路径下查找str函数库
$ gcc -o test1 main.c -L./ -lstr    //-L指定路径,指定在当前路径下查找str函数库

注意:在使用-l选项时,-o选项的目的名称要在-l链接的库名称之前,否则gcc会认为-l是生成的目标而出错。

生成动态链接库

动态链接库是程序运行是加载的库,当动态链接库正确安装后,所有的程序都可以使用动态库来运行程序。动态练级库是目标文件的集合,目标文件在动态链接库中的组织方式是按照特殊形式形成的,苦衷函数和变量的地址是相对地址,不是绝对地址,其真实地址是在调用动态库的程序加载是形成的。
动态链接库的名称有别名(soname)、真名(realname)和连接名(linker name)。
别名:由一个前缀lib,然后是库的名字,再加上一个后缀“.so”构成;
真名:动态链接库的真实名称,一版总是在别名的基础上加上一个小版本号、发布版本等构成。
链接名:程序链接时使用的名字。

生成动态链接库

使用-fPIC选项或者-fpic选项。例如下面的命令将string.c编译生成动态链接库:

$ gcc -shared -Wl,-soname,libstr.so -o libstr.so.1 string.c

其中“-soname,libstr.so”表示生成动态库的别名是libstr.so;“-o libstr.so.1”选项则表示是生成名字为libstr.so.1的实际动态链接库文件;-shared告诉编译器生成一个动态链接库。
生成动态链接库之后一个很重要的问题就是安装,一般情况下将生成的动态链接库赋值到系统默认的动态链接库的搜索路径下,通常有/lib、/usr/lin、/usr/local/lib,方到以上任何一个目录下都可以。

动态链接库的配置

在运行的程序中使用动态链接库,需要指定系统的动态链接库搜索的路径,让系统找到运行需要的动态链接库才可以。系统中的配置文件/etc/ld.so.conf是动态链接库的搜索路径配置文件。在这个文件内存放着可被Linux共享的动态链接库所在的目录的名字。通过如下命令可以查看系统中的动态链接库配置文件的内容:

$ cat /etc/ld.so.conf
include /etc/ld.so.conf.d/*.conf

Ubuntu的配置文件将目录/etc/ld.so.conf.d中的配置文件包含进来,对这个目录下的文件进行查看:

 $ ls /etc/ld.so.conf.d/
GL.conf  libasound2.conf  vmware-tools-libraries.conf
i486-linux-gnu.conf  libc.conf
$ cat /etc/ld.so.conf.d/i486-linux-gnu.conf 
# Multiarch support
/lib/i486-linux-gnu
/usr/lib/i486-linux-gnu
动态链接库管理命令

为了让新增的动态链接库能够被系统共享,需要运行动态链接库的管理命令ldconfig。其作用是:在系统的默认搜索路径,和动态链接库配置文件中所列出的目录里搜索动态链接库,创建动态链接库装入程序需要的连接和缓存文件。搜索完毕后将结果写入缓存文件/etc/ld.so.cache中,文件中保存的是已经排好序的动态链接库的名字列表。
以下主要介绍ldconfig的几个常用命令,其它的可以通过man指令或者ldconfig –help进行查看。
查看系统中已有的动态链接库:

$ldconfig –p   //库太多就不在一一列写了
在缓冲区“/etc/ld.so.cache”中找到 1030 个库
    libzephyr.so.4 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libzephyr.so.4
    libzeitgeist-2.0.so.0 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libzeitgeist-2.0.so.0
    libzeitgeist-1.0.so.1 (libc6,x86-64) => /usr/lib/libzeitgeist-1.0.so.1
    libz.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/libz.so.1
    libz.so.1 (libc6) => /usr/lib32/libz.so.1
    libz.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libz.so
    libyelp.so.0 (libc6,x86-64) => /usr/lib/libyelp.so.0
    libyaml-0.so.2 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libyaml-0.so.2
    libyajl.so.2 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libyajl.so.2
    libx86.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/libx86.so.1
    libxtables.so.10 (libc6,x86-64) => /lib/libxtables.so.10
    libxslt.so.1 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libxslt.so.1
        libxshmfence.so.1 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libxshmfence.so.1
…………

使用选项-v会将ldconfig在运行过程中扫描到的目录和共享库信息输出到中断,用户可以看到运行的结果和中间信息,这里就不在意义列举了。
当用户的目录并不在动态链接库配置文件/etc/ld.so.conf中指定的时候,可以使用ldconfig命令显示制定要扫描的目录,将用户指定目录中的动态链接库放入系统中进行共享。命令格式为:ldconfig 目录名
注意:如果在运行上述命令后,再次运行ldconfig而没有加参数,系统会将/lib、/usr/lib以及/etc/ld.so.conf中指定目录中的动态库加入缓存,这时候上述代码中的动态链接库可能不被系统共享了

使用动态链接库

在编译程序时,使用动态链接库和静态链接库是一致的,使用“-l库名”的方式。

$ gcc -o test1 main.c -L./ -lstr

这时执行test1文件会出如下问题:

$ ./test1
./test1: error while loading shared libraries: libstr.so: cannot open shared object file: No such file or directory

这是由于程序运行时没有找到动态链接库造成的。
解决办法:

  • 将动态链接库的目录放到程序搜索路径中,可以将库的路径加到环境变量LD_LIBRARY_PATH中实现,例如:
$ export LD_LIBRARY_PATH=/home/ych/Desktop/test/string: $LD_LIBRARY_PATH
  • 另一种方法是使用ld-linux.so.2来加载程序,命令格式为:
    /lib/ld-linux.so.2 –library-path 路径 程序名
    注意:如果系统的搜索路径下同时存在静态库和动态链接库,默认情况下会连接动态库。如果需要强制连接静态连接库,需要加上“-static”选项,即上述的编译方法改为如下的方式:
$ gcc -o test1 main.c -static -lstr
动态加载库

动态加载库和一版的动态链接库所不同的是,一版动态链接库在恒旭启动的时候就要寻找动态库,找到库函数;而动态加载库可以用程序的方式来控制什么时候加载。动态加载库主要有函数dlopen()、deerror()、dlsym()和dlclose().
这里的就不在详细介绍了,后续会写文章专门描述动态加载库。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值