from: http://www.techug.com/linux-static-lib-dynamic-lib

库的存在极大的提高了C/C++程序的复用性,但是库对于初学者来说有些难以驾驭,本文从Linux的角度浅谈Linux下的静态库、动态库和动态加载库。

Linux库类型

Linux下可以创建两种类型的库:

  1. 静态库(.a): 在链接期间被应用程序直接链接进可执行文件
  2. 动态链接库(.so): 动态库还分为两种用法: a) 应用程序运行期间链接动态库,但是在编译期间声明动态库的存在,也就是说这种动态库必须在编译时对编译器可见,但编译器却不将此种库编译进可执行文件; b) 在运行期间,动态加载和卸载的库,使用动态加载方法加载。这种库的形式跟动态链接没有本质区别,区别是在调用时,是由用户程序决定何时链接的,而不是由系 统链接器自动链接

命名约定

库需要以lib作为开头,而在指定链接命令行参数时,却无需包含开头和扩展名,例如:

gcc src-file.c -lm -lpthread

这个例子中,链接了libmath.alibpthread.a

静态库(.a)

生成静态库的方法如下:

  • 编译object文件。例如:cc -Wall -c ctest1.c ctest2.c,该命令会生成ctest1.octest2.o(其中-Wall表示编译时输出警告)。
  • 创建库文件。例如:ar -cvq libctest.a ctest1.o ctest2.o。该命令会得到一个libctest.a文件
  • 可以通过ar -t查看.a文件中包含哪些.o。所以,实际上ar就是一个打包命令,类似tar
  • 构建符号表。ranlib libctest.a用于为.a创建符号表。有些ar命令实际上已经集成了ranlib的功能

.a文件与windows下的.lib是相同的概念。

动态库(.so)

生成动态库的方法如下:

  • 编译object文件时使用-fPIC选项:

    gcc -Wall -fPIC -c *.c

这个选项的目的是让编译器生成地址无关(position independent)的代码,这是因为,动态库是在运行期间链接的,变量和函数的偏移量是事先不知道的,需要链接以后根据offset进行地址重定向。

  • 使用-shared链接

    gcc -shared -Wl,-soname,libctest.so.1 -o libctest.so.1.0 *.o

-shared选项是让动态库得以在运行期间被动态链接;-Wl,options是设置传递给ld(链接器)的参数,在上面的例子中,当链接器在链接.o时会执行ld -soname ibctest.so.1

  • 创建软链

上面的命令将最终输出一个动态库libctest.so.1.0,而出于习惯,会创建两个软链:

mv libctest.so.1.0 /opt/lib
ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so.1
ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so

libctest.so用于在编译期间使用-lctest让编译器找到动态库,而libctest.so.1用于在运行期间链接

gcc -Wall -I/path/to/include-files -L/path/to/libraries prog.c -lctest -o prog

查看依赖

使用ldd命令来查看程序对动态库的依赖。例如:

ldd proglibctest.so.1 => /opt/lib/libctest.so.1 (0x00002aaaaaaac000)
libc.so.6 => /lib64/tls/libc.so.6 (0x0000003aa4e00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003aa4c00000)

obj文件

obj文件的格式和组成可能是系统差异性的一大体现,比如windows下的PElinux和一些unix下的elfmacosmach-oaix下的xcoff

查看obj文件的符号表信息,可以通过nm objdump readelf等方法。

运行期间查找动态库

运行期间,系统需要知道到哪里去查找动态库,这是通过/etc/ld.so.conf配置的。ldconfig用于配置运行时动态库查找路径,实际是更新/etc/ld.so.cache。另外一些环境变量也可以影响查找:(Linux/Solaris: LD_LIBRARY_PATH, SGI: LD_LIBRARYN32_PATH, AIX: LIBPATH, Mac OS X: DYLD_LIBRARY_PATH, HP-UX: SHLIB_PATH)

动态加载和卸载的库

需要应用程序希望设计成插件化的架构,这就需要可以动态加载和卸载库的机制。与动态链接不同的是,动态加载的意思是,编译期间可以对动态库的存在一无所知,而是在运行期间通过用户程序尝试加载进来的。

通过dlfcn.h中的dlopendlsymdlclose等函数实现此种功能。

另外,使用到dlfcn机制的可执行文件需要使用-rdynamic选项,它将指示连接器把所有符号(而不仅仅只是程序已使用到的外部符号,但不包括静态符号,比如被static修饰的函数)都添加到动态符号表(即.dynsym表)里。

GNU Libtool

如今许多软件的编译都采用libtool工具,libtool是一个编译链接包装工具,实际只是一个脚本,用libtool编译和链接会产生类似.la的文件,.la这种文件其实是个文本文件,指向.a文件,并声明一些版本信息。

Linux下的静态库、动态库和动态加载库相关推荐

  1. Linux下快速静态编译Qt以及Qt动态/静态版本共存

    Qt下静态编译Qt,根据我的经验,如果按照Windows下那种直接拿官方sdk安装之后的文件来编译是行不通的,需要直接下载Qt的source包,目前诺基亚的源码叫做qt-everywhere-open ...

  2. Linux下--解决网易云音乐个性推荐无法加载的问题

    之前删除重装了好几次都不成功,因为重新安装后之前的配置文件都还在,于是进行了下面的操作 find /home -name netease-cloud-music 发现了这个文件夹 /home/numb ...

  3. linux下生成静态库和动态库

    linux下生成静态库和动态库 一.动态库.静态库简介 库是写好的现有的,成熟的,可以复用的代码.现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常.本质上 ...

  4. Linux下的静态链接库和动态链接库编程

    Linux下的静态链接库和动态链接库编程 参考: Linux下的静态链接库和动态链接库编程 - Histring - 博客园 Mac下静态库和动态库的创建和使用_C/C++_vincent2610的专 ...

  5. Linux下的静态链接库和动态链接库

    Linux下的静态链接库和动态链接库 零.链接库概述 Linux下得库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀.面对比一下两者: 静态链接库:当要使用时,连接器会找出程序所需的函数, ...

  6. 静态链接库、动态链接库和动态加载库

    前言 静态库是obj文件的一个集合(目标文件中通常仅解析了文件内部的变量和函数,对于引用的函数和变量还没有解析,这需要将其他已经编写好的目标文件引用进来,将没有解析的函数和变量进行解析,通常引用的目标 ...

  7. C语言 | Linux下的静态链接与动态链接

    1024G 嵌入式资源大放送!包括但不限于C/C++.单片机.Linux等.关注微信公众号[嵌入式大杂烩],回复1024,即可免费获取! 前言 上一篇分享了静态链接与动态链接的实验(Windows): ...

  8. 关于在linux下出现stdio.h文件不存在等gcc标准库不能找到的解决的方法

    关于在linux下出现stdio.h文件不存在等gcc标准库不能找到的解决的方法 参考文章: (1)关于在linux下出现stdio.h文件不存在等gcc标准库不能找到的解决的方法 (2)https: ...

  9. linux dlopen 内存,Linux下加载库的有关问题(dlopenm, dlsym)

    Linux下加载库的问题(dlopenm, dlsym) 如题, 程序中发现load库成功,但是加载函数的时候报错: undefined symbol functionname 是很简单的一个东西,因 ...

最新文章

  1. webpack打包缓存_【第835期】Webpack 的静态资源持久缓存
  2. visudo使用-怎样将mount权限给普通用户
  3. 蓝桥杯真题 a组 java_2014蓝桥杯决赛A组第5题(java)
  4. [转] 2016前端开发技术巡礼
  5. 华为stfal00是什么手机_opporeno5pro和华为p40pro有什么区别 哪款手机更好
  6. linux c字符连接,C 语言实例
  7. android 2.3 otg,学会使用手机的OTG功能-事半功倍-系列评测2
  8. js 的基础知识变量
  9. 基于机器视觉的Data Matrix二维码识别
  10. python socket tcp实战_Python socket.TCP_MAXSEG属性代码示例
  11. 【代码笔记】iOS-MBProgressHUD+MJ
  12. 数据库、SID实例、Oracle数据库、sys、system用户
  13. 在线HTTP接口测试 - HTTP GET/POST模拟请求测试工具
  14. 网页采集器,全自动网站采集发布(图文)
  15. java dwg转pdf_java实现CAD图纸文件DWG格式转为PDF格式
  16. [Python] 网络设备巡检脚本
  17. 杀戮尖塔是用java_杀戮尖塔修改class文件图文教程
  18. pandas取两个dataframe中不同的行
  19. python仙修之 入门之后不放弃?
  20. Excel填充空白的单元格

热门文章

  1. 用python抓取糗事百科的小程序
  2. java 自己抛空指针异常_java Timetask 访问service 抛空指针异常解决方案
  3. checkpoint技术mysql_认识MySQL中的Checkpoint技术
  4. FTP 主动、被动工作模式
  5. JavsScript与时间相关的函数
  6. 32 墨水屏股票显示器_炒股护眼新选择 | 电子墨水显示器amp;平板盯盘效果(附视频)...
  7. leetcode算法题--增量元素之间的最大差值
  8. leetcode算法题--打家劫舍II
  9. php mysql特殊符号过滤微信小程序_微信小程序数据过滤(filter)方法
  10. 炉石传说服务器维护有补偿吗,炉石传说官网维护补偿什么时候到 未到原因说明...