您的位置:首页 > 运维架构 > Linux

Linux下的静态库和动态库的使用和制作

2017-09-03 12:08 260 查看
1.库在本质上可以说是一个可执行的二进制文件。
两者的区别:
静态库的代码在编译过程已经被载入可执行程序,因此体积较大。
共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小

2.静态库:
静态库的名字一般是libxxx.a,xxx为库的名字。利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。当然这也会成为他的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译。

3.动态库:
动态库的名字一般是libxxx.M.N.so,同样的xxx为库的名字,M是库的主版本号,N是库的副版本号。当然也可以不要版本号,但名字必须有。相对于静态函数库,动态函数库在编译的时候并没有被编译进目标代码中,你的程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。

4.静态库的制作:

(1) 为hello1和hello2生成目标文件

gcc -O -c hello1.c   hello2.c

然后制作库;(库的命名开头都是以lib 开头,静态库的后缀是.a)

ar -crsv libpr.a pr1.o pr2.o

ar -t libpr.a  //显示静态库所依赖的文件

5.动态库的制作:(动态库的后缀是.so)

(1)生成动态库  xxx.so

gcc -fPIC -Wall -c pr1.c pr2.c

PIC告诉编译器产生与位置无关代码(Position-Independent Code), 则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。

gcc -shared -o libpr.so pr1.o pr2.o

or use one line:

gcc -O -fPIC -shared -o libpr.so pr1.c pr2.c

(2)编译时调用动态库  

gcc -o test main.c –L. -lpr

采用该方法执行会报告./test: error while loading shared libraries: libpr.so: cannot open shared object file: No such file or directory

原因:因为在动态函数库使用时,会查找/usr/lib、/lib目录下的动态函数库,而此时我们生成的库不在里边。

解决方法:

1.最直接最简单的方法就是把so拉到/usr/lib或/lib中去,需要root权限,在别人的电脑上会很麻烦;会把系统目录弄得混乱。



2.新建并编辑/etc/ld.so.conf.d/my.conf文件,加入库所在目录的路径,执行ldconfig命令更新ld.so.cache文件但是需要root权限。



3.export LD_LIBRARY_PATH=/tmp

不过这样export
只对当前shell有效,当另开一个shell时候,又要重新设置。可以把export
LD_LIBRARY_PATH=/tmp 语句写到 ~/.bashrc中,这样就对当前用户有效了,写到/etc/bash.bashrc中就对所有用户有效了。

echo $LD_LIBRARY_PATH

不过LD_LIBRARY_PATH的设定作用是全局的,过多的使用可能会影响到其他应用程序的运行,所以多用在调试。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: