Linux静态库和动态库
在windows平台和linux平台下都大量存在着库。本质上来说库是一种可执行的二进制代码(但不可以独立执行),可以被操作系统载入内存执行。
Linux下的库有两种:静态库和动态库(共享库)。
本文将介绍Linux下静态库和动态库的概念以及相应的创建与使用方法,文章内容为个人学习笔记,欢迎指正。
1 对比
类型 | 特点 |
---|---|
静态库 | 在编译时被链接到程序中,作为可执行程序的一部分。在程序运行时不再依赖静态库,占用内存大 |
动态库 | 在可执行程序运行时载入内存。动态库已经在内存中不需要再次载入 |
2 静态库
2.1 概念
静态库指将所有相关的目标文件打包成为一个单独的文件,即静态库文件
。
静态库以.a
结尾,链接器会将程序中使用到的函数的代码从库文件中拷贝到程序中。
由于每个使用静态库的应用程序都需要拷贝所有函数的代码,所以静态链接的文件会比较大。
在Unix系统中,静态库以一种称为存档(archive)
的特殊文件格式存放在磁盘中。
存档文件是一组连接起来的可重定位目标文件的集合,有一个头部用来描述每个成员目标文件的大小和位置。
2.2 静态库的创建和使用
2.2.1 环境准备
创建根文件夹staticDemo
:
创建子文件夹include
,用于存放所有头文件:
进入include文件夹,编写myLib.h
文件,申明printInfo()
函数:
进入上层目录,创建lib
文件夹,用于存放所有库文件,再其中编写print.c
文件,使用了myLib.h
中的printInfo()
函数:
进入上层目录,编写main.c
文件,用于测试:
准备工作到此完成,整个目录结构如下:
2.2.2 生成静态库
首先进入lib文件夹,生成print.o
文件:
使用ar命令
归档目标文件,得到静态库:
上述命令中crv
是ar
的命令选项:
-
c 如果需要生成新的库文件,不要警告
-
r 代替库中现有的文件或者插入新的文件
-
v 输出详细信息
使用-t参数
可以查看静态库中包含的文件:
注意:我们要生成的库的文件名必须形如libxxx.a
,这样我们在链接这个库时,就可以用-lxxx
。
反过来讲,当我们告诉编译器-lxxx
时,编译器就会在指定的目录中搜索libxxx.a
或是libxxx.so
。
2.2.3 生成可执行文件
进入上层目录,链接库并生成可执行文件:
执行可执行文件:
3 动态库
3.1 概念
动态库是一个目标模块
,Linux系统以.so
后缀表示,Windows以.dll
后缀表示,使用动态库可以减小应用程序占用的空间和加载时间。
在运行时,可以加载
到任意的存储器地址,并和一个再存储器中的程序链接起来,这个过程称为动态链接,是由一个叫做动态链接器
的程序来执行的。
动态库是Linux系统最广泛的一种程序使用方式,工作原理是相同功能的代码可以被多个程序共同使用。
在程序加载的时候,内核会检查程序使用到的动态库是否已经加载到内存:
-
如果没有被加载到内存,则从系统库路径搜索并且加载到相关的动态库。
-
如果动态库已经被加载到内存,程序可以直接使用而无需加载。
应用程序在自身加载时和运行过程中动态链接和加载动态库。
3.2 动态库的创建和使用
3.2.1 环境准备
创建根文件夹dynamicDemo
:
创建子文件夹include
,用于存放所有头文件:
进入include文件夹,编写myLib.h
文件,申明printInfo()
函数:
进入上层目录,创建lib
文件夹,用于存放所有库文件,再其中编写print.c
文件,使用了myLib.h
中的printInfo()
函数:
进入上层目录,编写main.c
文件,用于测试:
准备工作到此完成,整个目录结构如下:
3.2.2 生成动态库
进入lib文件夹,给gcc加入-fPIC参数
,生成print.o文件:
使用gcc的-shared参数
生成动态库libprint.so:
3.2.3 生成可执行文件
进入dynamicDemo
目录,链接库并生成可执行文件:
注意:如果同一目录下同时存在同名的动态库和静态库,比如libprint.so
和libprint.a
都在当前路径下,则gcc会优先链接动态库。
执行可执行文件:
系统报错找不到libprint.so
,原来Linux是通过/etc/ld.so.cache
文件搜寻要链接的动态库的。而/etc/ld.so.cache
是ldconfig
程序读取/etc/ld.so.conf
文件生成的。(注意,/etc/ld.so.conf
中并不必包含/lib
和/usr/lib
,ldconfig
程序会自动搜索这两个目录)
这里我们指定环境变量来找到动态库路径,在下一节中会有详细介绍:
3.3 设置动态库的搜索路径
3.3.1 LD_LIBRARY_PATH
LD_LIBRARY_PATH
是Linux环境变量名,该环境变量主要用于在查找动态库时搜索默认路径之外的其他路径。
通常,Linux搜索动态库的默认路径是/lib
和/usr/lib
。LD_LIBRARY_PATH
路径优先级大于系统默认路径。
3.3.2 rpath
gcc的-R
或者-rpath
选项在编译链接时指定动态库路径,并且将动态库路径保存到可执行文件中。
运行可执行文件时直接到该路径下查找动态库,而不依赖于默认路径或者环境变量。
采用这种方式,每个程序可以设定独立的动态库位置,而不会像LD_LIBRARY_PATH
环境变量那样影响其他程序。
3.3.3 ldconfig
ldconfig
是一个动态链接库管理命令。该命令的用途是在默认路径(/lib
和/usr/lib
)以及动态库配置文件/etc/ld.so.conf
内所包含的目录下,搜索动态库,然后为动态载入程序(ld.so)
创建动态库列表的缓存文件(/etc/ld.so.cache)
。
3.3.3.1 加入标准路径
这里以放入/usr.lib文件夹为例:
更新缓存:
查看动态库:
编译执行:
3.3.3.2 加入配置文件
首先查看/etc/ld.so.conf
文件:
可以看到其包含了ld.so.conf.d
目录,因此自定义配置文件libprint.conf
加入到/etc/ld.so.conf.d
文件夹中,配置文件中包含该程序的动态库路径:
更新缓存:
查看动态库:
编译执行:
参考文献
[1] JollyWing. Linux静态库生成指南[EB/OL]. http://www.cnblogs.com/jiqingwu/p/4325382.html.
[2] JollyWing. Linux动态库生成与使用指南[EB/OL]. http://www.cnblogs.com/jiqingwu/p/linux_dynamic_lib_create.html.
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
CentOS查找所有文件中某个字符串
查找目录下的所有文件中是否含有某个字符串 find .|xargs grep -ri "IBM" 查找目录下的所有文件中是否含有某个字符串,并且只打印出文件名 find .|xargs grep -ri "IBM" -l (1)find命令的一般形式 find pathname -options [-print -exec -ok] pathname :find命令所查找的目录路径。如用"."来表示当前的目录,用/来表示系统根目录 -print :find命令将匹配的文件输出到标准输出 -exec: find命令对匹配的文件执行该参数所给出的shell命令,相应的命令形式为 'command'{} \; (注意{}和\之间的空格) -ok 和 -exec的作用相同,只不过以一种更为安全的模式来执行该参数所给出的shell命令,在执行每一个命令之前,都会给出提示,让用户来确定是否执行。 options有如下几种: -name :按照文件名查找文件 -perm :按照文件权限来查找文件 -user :按照文件属主来查找文件 -...
- 下一篇
CentOS删除一个文件夹下面的多个文件夹
linux删除一个文件夹下面的多个文件夹 Linux删除用 rm命令,删除不提示\rm 1、若在当前目录下删除多个文件和文件夹 可以直接删除:\rm -r fileUpload.jsp include res WEB-INF 文件和文件夹之间用空格隔开 2.要删除的文件和文件夹不在当前目录下,需要使用下面的方式删除 删除命令:\rm -r test/day2/webapp1/{template,res,WEB-INF} {}内是要删除的文件和文件夹
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Red5直播服务器,属于Java语言的直播服务器
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- CentOS6,CentOS7官方镜像安装Oracle11G
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS8编译安装MySQL8.0.19