动态库与静态库本质是二进制的源代码,只是人看不懂,对机器没有影响。
静态库的制作和使用
命名规则:
名字一般分为三部分,开头为“lib”,表示这是一个库文件,接下来是想取的名字,最后是后缀“.a”(windows下是lib)。例如:libhello.a
制作步骤:
1.原材料:源代码
2.将.c生成.o
3.将-o打包:ar rcs 静态库的名字 .o文件
静态库的使用:
将使用到库的文件与其进行连接:
gcc -I 头文件目录 -L 库目录 -l 库名字 -o 可执行文件名
//这个库名字就是抛去lib前缀和.a后缀的文件名
优点:
1.静态库被打包到应用程序中,加载速度快;
2.发布程序无需提供静态库,移植方便。
缺点:
1.销毁系统资源,浪费内存;
2.更新、部署、发布麻烦。
动态库的制作与使用
命名规则:
名字一般分为三部分,开头为“lib”,表示这是一个库文件,接下来是想取的名字,最后是后缀“.so”(windows下是dll)。例如:libhello.so
制作步骤:
1.原材料:源代码
2.将.c生成.o:
gcc a.c b.c -c -fpic
3.将-o打包:
gcc -shared -o libxxx.so a.o b.o
静态库的使用:
将使用到库的文件与其进行连接:
gcc -I 头文件目录 -L 库目录 -l 库名字 -o 可执行文件名
//这个库名字就是抛去lib前缀和.so后缀的文件名
解决动态库加载失败的问题
动态库直接按上面的方式使用,可能会出现没有找到该文件的情况。这种情况的出现是由于动态库的工作模式与静态库的工作模式不同所导致。
动态库在打包的时候使用的是gcc命令,这样生成的文件是elf格式的,对于elf格式的可执行程序,是由ld-linux.so*来完成的,它先后搜索elf文件的DT_RPATH段——环境变量LD_LIBRARY_PATH——/etc/ld.so.cache文件列表——/lib/或/user/lib/目录,找到库文件后将它载入内存。
方法一:使用环境变量让系统找到库:
临时设置:
在终端输入:export LD_LIBRARY_PATH = 动态库路径(最好是绝对路径): $LD_LIBRARY_PATH
最后的:和之后部分表示对原有内容做拼接操作,避免覆盖变量中原有的值。
这种方式在当前终端中有效,重开一个终端仍然找不到。
永久设置:
用户级别:
将以上的语句写入~/.bashrc
配置完成后需重启终端或输入命令:source ~/.bashrc
系统级别:
将以上语句写入/etc/profile
配置完成后需重启电脑或输入命令:source /etc/profile.
方法二:更新/etc/ld.so.cache文件列表
找到配置文件:
打开etc/ld.so.conf,将动态库的绝对路径写入。
执行命令:
sudo ldconfig -v
优点:
1.可实现进程间资源共享;
2.程序升级简单;
3.可以控制何时加载动态库;
4.动态库在内存中只占一份内存(共享区),避免了资源的浪费。
缺点:
1.加载速度比静态库慢;
2.发布程序需要提供所依赖的动态库