文档章节

关于linux下的共享库(动态库)和静态库

AlphaJay
 AlphaJay
发布于 2010/04/15 12:41
字数 1602
阅读 3.1K
收藏 2

 

1.什么是库
windows平台和linux平台下都大量存在着库。
质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。
由于windowslinux的本质不同,因此二者库的二进制是不兼容的
本文仅限于介绍linux下的库

 

2.库的种类
linux
下的库有两种:静态库和共享库(动态库)。

 二者的不同点在于代码被载入的时刻不同。
静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。
共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小。

 

3.库存在的意义
是别人写好的现有的,成熟的,可以复用的代码,你可以使用但要记得遵守许可协议。
现实中个程序都要依赖很多基础的底层库不可能每个人的代码都从零开始,因此库的存在意义非同寻常。共享库的好处是,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。

 

4.库文件是如何产生的在linux
静态库的后缀是.a,它的产生分两步
Step 1.
源文件编译生成一堆.o,每个.o里都包含这个编译单元的符号表
Step 2.ar
命令将很多.o转换成.a,成文静态库
动态库的后缀是.so,它由gcc加特定参数编译产生
例如:
$ gcc -fPIC -c *.c $ gcc -shared -Wl,-soname, libfoo.so.1 -o libfoo.so.1.0 *.

 

5.库文件是如何命名的,有没有什么规范
linux下,库文件一般放在/usr/lib和/lib下,
静态库的名字一般为libxxxx.a,其中xxxx是该lib的名称
动态库的名字一般为libxxxx.so.major.minorxxxx是该lib的名称,major是主版本号, minor是副版本号

 

6.如何知道一个可执行程序依赖哪些库
ldd
命令可以查看一个可执行程序依赖的共享库,
例如# ldd /bin/lnlibc.so.6
=> /lib/libc.so.6 (0×40021000)/lib/ld-linux.so.2
=> /lib/ld- linux.so.2 (0×40000000)
可以看到ln命令依赖于libc库和ld-linux

 

7.可执行程序在执行的时候如何定位共享库文件
当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径
此时就需要系统动态载入器(dynamic linker/loader)
对于elf格式的可执行程序,是由ld-linux.so*来完成的

它先后搜索elf文件的 DT_RPATH环境变量LD_LIBRARY_PATH—/etc/ld.so.cache文件列表—/lib/,/usr/lib目录

找到库文件后将其载入内存

 

8.在新安装一个库之后如何让系统能够找到他
如果安装在/lib或者/usr/lib下,那么ld默认能够找到,无需其他操作
如果安装在其他目录,需要将其添加到/etc/ld.so.cache文件中,步骤如下
1.
编辑/etc/ld.so.conf文件,加入库文件所在目录的路径
2.
运行ldconfig,该命令会重建/etc/ld.so.cache文件

  

############################################################

  

 linux中编译静态库(.a)和动态库(.so)的基本方法

 

静态库 
 

linux环境中, 使用ar命令创建静态库文件.如下是命令的选项:
          d -----
从指定的静态库文件中删除文件

          m -----
把文件移动到指定的静态库文件中

          p -----
把静态库文件中指定的文件输出到标准输出

          q -----
快速地把文件追加到静态库文件中

          r -----
把文件插入到静态库文件中

          t -----
显示静态库文件中文件的列表

          x -----
从静态库文件中提取文件

     
还有多个修饰符修改以上基本选项,详细请man ar 以下列出三个
:
          a -----
把新的目标文件(*.o)添加到静态库文件中现有文件之后

          b -----***************************************
之前

          v -----
使用详细模式

ar 命令的命令行格式如下:
      ar [-]{dmpqrtx}[abcfilNoPsSuvV] [membername] [count] archive files...
参数archive定义库的名称, files是库文件中包含的目标文件的清单, 用空格分隔每个文件
.
 

比如创建一个静态库文件的命令如下:
      ar r libapue.a error.o errorlog.o lockreg.o
这样就了libapue.a静态库文件, 可以用 t 选项显示包含在库中的文件
 
创建库文件之后,可以创建这个静态库文件的索引来帮助提高和库连接的其他程序的编译速度

使用ranlib程序创建库的索引,索引存放在库文件内部.
      ranlib libapue.a
 

nm程序显示存档文件的索引,它可以显示目标文件的符号
nm libapue.a | more
如果是显示目标文件的符号
:
nm error.o | more
如何使用呢?如下所示
:
gcc -o test test.c libapue.a
这样就可以在test.c中调用在libapue.a中的函数了.

  

 

动态库


1.
创建共享库

     gcc -shared -o libapue.so error.o errorlog.o
这样就创建了共享库
!
2.
编译共享库

   
假设共享库位于当前目录(即跟程序文件相同的目录中
)
gcc -o test -L. -lapue test.c
这样就编译出了不包含函数代码可执行文件了,但是但你运行时会发现linux动态加载器找不到libapue.so文件
.
可以用ldd 命令查看可执行文件依赖什么共享库
:
ldd test
如何才能让动态加载器发现库文件呢?有两种方法可以解决

    
1.环境变量
       export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:."
    2.
修改/etc/ld.so.conf文件.

  

一般应用程序的库文件不与系统库文件放在同一个目录下,一般把应用程序的共享库文件放在/usr/local/lib,新建一个属于自己的目录apue,然后把刚才libapue.so复制过去就行了
同时/etc/ld.so.conf中新增一行
:
/usr/local/lib/apue


以后在编译程序时加上编译选项
:
-L /usr/local/lib/apue -lapue

 

/*

参数的配置通过man gcc可以看到

-llibrary

              连接名为 library 库文件. 

              连接器 标准搜索目录 寻找 这个 库文件, 库文件 真正  

本文转载自:http://www.360doc.com/content/09/0618/17/150654_3946451.shtml

AlphaJay
粉丝 79
博文 284
码字总数 313790
作品 0
杭州
私信 提问
关于Linux静态和动态链接库的创建及使用

和Windows系统一样Linux也有静态/动态链接库,下面介绍创建和使用方法: 假设有下面几个文件: 头文件String.h,声明相关函数原形,内容如下: Strlen.c:函数Strlen的实现,获取给定字符串的...

zt371
2009/05/08
639
0
在Linux平台上如何使用接静态库和共享库

1、Linux函数库介绍 函数库可以看做是事先编写的函数集合,它可以与主函数分离,从而增加程序开发的复用性。Linux中函数库可以有3种使用的形式:静态、共享和动态。 1) 静态库的代码在编译时...

晨曦之光
2012/03/09
2K
0
静态库与共享库制作与应用

1、什么是库 在windows平台和linux平台下都大量存在着库。本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。由于windows和linux的本质不同,因此二者库的二进制是不兼...

长平狐
2012/09/03
258
0
Linux下静态库和动态库(共享库)的制作与使用

Linux下静态库和动态库(共享库)的制作与使用 Linux操作系统支持的函数库分为静态库和动态库,动态库又称共享库。linux系统有几个重要的目录存放相应的函数库,如/lib /usr/lib。 静态函数库...

木雨山
2011/07/29
121
0
关于Linux静态库和动态库的分析

1.什么是库 在windows平台和linux平台下都大量存在着库。 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。 由于windows和linux的本质不同,因此二者库的二进制是不...

YACHE
2011/07/04
121
0

没有更多内容

加载失败,请刷新页面

加载更多

mysql中int(11)的列大小是多少?

mysql中int(11)的列大小是多少? 以及可以在此列中存储的最大值? #1楼 mysql中int(11)的列大小是多少? (11) int数据类型的此属性与列的大小无关。 它只是整数数据类型的显示宽度。 从11....

技术盛宴
27分钟前
19
0
聊聊artemis消息的推拉模式

序 本文主要研究一下artemis消息的推拉模式 拉模式 receive activemq-artemis-2.11.0/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessageConsumer.......

go4it
36分钟前
39
0
vue 全局前置守卫引起死循环的原因与解决方法

我们经常会用到全局前置守卫,如判断用户有没有登陆过,如果登陆过就直接跳到目的页面,如果没有登陆过,就跳转到登陆页。 先看官网对全局前置守卫的介绍 使用 router.beforeEach 注册一个全...

tianyawhl
47分钟前
31
0
如何按索引从std :: vector <>擦除元素?

我有一个std :: vector <int>,我想删除第n个元素。 我怎么做? std::vector<int> vec;vec.push_back(6);vec.push_back(-17);vec.push_back(12);vec.erase(???); #1楼 erase方法将以两......

javail
今天
43
0
使用生成器模拟时间分片

对于cpu密集型任务, 时间分片可以有效减少页面卡顿, 不过对于纯计算型任务还是推荐使用worker在后台做计算 效果图, 计算密集型任务被分到每次只执行16ms, 每次执行完毕留给浏览器时间去响应事...

阿豪boy
今天
63
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部