当前位置:首页 > 图片 > 军情话题 > 正文
文章正文

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

图片 > 军情话题 > :linux动态库的使用 Linux下动态库和静态库的制作及使用是由美文导刊网(www.eorder.net.cn)为您精心收集,如果觉得好,请把这篇文章复制到您的博客或告诉您的朋友,以下是linux动态库的使用 Linux下动态库和静态库的制作及使用的正文:

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

在实际的开发过程中,编写程序往往都需要依赖很多基础的底层库,比方说平时用的较多的标准C库,数学库等等;我们会频繁的使用这些库里的函数,这些函数大多数都是前人为我们写好的,所以值得庆幸的是我们的工作不必从零开始,我们要做的只是在恰当的位置调用合适的库函数去实现相应的功能,充分利用前人的劳动成果,就是“站在巨人的肩膀上”。本文主要简述Linux下库的制作以及使用方法。

一、什么是库

库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行。根据链接时期的不同,库又有:静态库和共享库(动态库)二者的不同点在于代码被载入的时刻不同。

静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。

共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小。

二、初识静态库与动态库

1.静态函数库

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

2.动态函数库

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

三、静态库与动态库的比较

静态库其实从某种意义上来说只不过它操作的对象是目标代码而不是源码而已。因为静态库被链接后库就直接嵌入可执行文件中了,这样就带来了两个问题。

(1)首先就是系统空间被浪费了。这是显而易见的,想象一下,如果多个程序链接了同一个库,则每一个生成的可执行文件就都会有一个库的副本,必然会浪费系统空间。

(2)再者,一旦发现了库中有bug,挽救起来就比较麻烦了。必须一一把链接该库的程序找出来,然后重新编译。

而动态库的出现正弥补了静态库的以上弊端。因为动态库是在程序运行时被链接的,所以磁盘上只须保留一份副本,因此节约了磁盘空间。如果发现了bug或要升级也很简单,只要用新的库把原来的替换掉就行了。

但是静态库也有自己的优点:编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。

四、如何判断一个程序有没有链接动态库

(1)file命令

file程序是用来判断文件类型的,啥文件一看都清楚明了。

(2)ldd命令

看动态库,如果目标程序没有链接动态库,则打印“not a dynamic executable” (不是动态可执行文件)

五、静态库的制作

(1) 为pr1和pr2生成object文件

gcc -O -c pr1.c pr2.c

(2) ls

(3) 链接静态库

为了在编译程序中正确找到库文件,静态库必须按照 lib[name].a 的规则命名,如下例中[name]=pr.

ar参数意义:

c: create的意思

r:在库中插入模块(替换)。当插入的模块名已经在库中存在,则替换同名的模块。

s:写入一个目标文件索引到库中,或者更新一个存在的目标文件索引。

v:该选项用来显示执行操作选项的附加信息。

t:显示库的模块表清单。一般只显示模块名。

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

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

(4) 编译链接选项

-L 及-l 参数放在后面.其中,-L 加载库文件路径,-l 指明库文件名字.

gcc -o main main.c -L./ -lpr //生成main

-I后面接头文件 (大写的i)

-L后面接库文件路径路径

-l后面接库文件名,除了“lib”和“.a”部分,全名为libpr.a

(5)执行目标程序

./main

六、动态库的制作

注意,和动态库相关的路径搜索问题可以认为分链接时的搜索 和 运行时加载的搜索。链接时的搜索就是”-L”,比较简单直接,我们重点讲的是运行时的加载搜索。

(1)生成动态库 xxx.so

gcc -fPIC -Wall -c pr1.c

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

gcc -shared -o libpr.so pr1.o

or use one line:

gcc -O -fPIC -shared -o libpr.so pr1.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/bashrc中就对所有用户有效了。

echo $LD_LIBRARY_PATH

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

小结:

总而言之,静态库是以空间换时间,动态库是以时间换空间。无论你是在Linux平台还是Windows平台下做开发,库的使用都大同小异。熟练的使各种库,会给我们带来许多便利,减少工作的负担加快工程的进度,从此升职,加薪不是梦,希望对你有所帮助。

-------------------------------------------------------------

关注 华清远见 微信公众号,与10万个程序员做朋友。

每天下午17:30干货分享,我们不见不散~返回搜狐,查看更多

Linux 动态库与静态库制作及使用详解

来源:IBM

转自:Linux爱好者

作者:陈鲁

Linux 应用开发通常要考虑三个问题,即:1)在 Linux 应用程序开发过程中遇到过标准库链接在不同 Linux 版本下不兼容的问题; 2)在 Linux 静态库的制作过程中发现有别于 Windows 下静态库的制作方法;3)在 Linux 应用程序链接第三方库或者其他静态库的时候发现链接顺序的烦人问题。本文就这三个问题针对 Linux 下标准库链接和如何巧妙构建 achrive(*.a) 展开相关介绍。

两个要知道的基本知识

Linux 应用程序因为 Linux 版本的众多与各自独立性,在工程制作与使用中必须熟练掌握如下两点才能有效地工作和理想地运行。

  1. Linux 下标准库链接的三种方式(全静态 , 半静态 (libgcc,libstdc++), 全动态)及其各自利弊。

  2. Linux 下如何巧妙构建 achrive(*.a),并且如何设置链接选项来解决 gcc 比较特别的链接库的顺序问题。

三种标准库链接方式选项及对比

为了演示三种不同的标准库链接方式对最终应用程序产生的区别, 这里用了一个经典的示例应用程序 HelloWorld 做演示,见 清单 1 HelloWorld。

#include <stdio.h>

#include <iostream>

using std::cout;

using std::endl;

int main(int argc, char* argv[])

{

printf("HelloWorld!(Printed by printf)\n");

cout<<"HelloWorld!(Printed by cout)"<<endl;

return 0;

}

三种标准库链接方式的选项及区别见 表 1

表 1. 三种标准库链接方式的选项及区别

上述三种标准库链接方式中,比较特殊的是 半静态链接方式,主要在于其还需要在链接前增加额外的一个步骤:

ln -s g++ -print-file-name=libstdc++.a,作用是将 libstdc++.a(libstdc++ 的静态库)符号链接到本地工程链接目录。

-print-file-name 在 gcc 中的解释如下:

-print-file-name=<lib> Display the full path to library <lib>

为了区分三种不同的标准库链接方式对最终生成的可执行文件的影响,本文从两个不同的维度进行分析比较:

维度一:最终生成的可执行文件对标准库的依赖方式(使用 ldd 命令进行分析)

ldd 简介:该命令用于打印出某个应用程序或者动态库所依赖的动态库

涉及语法:ldd [OPTION]… FILE…

其他详细说明请参阅 man 说明。

三种标准库链接方式最终产生的应用程序的可执行文件对于标准库的依赖方式具体差异见 图 1、图 2、图 3所示:

图 1. 全静态标准库链接方式

图 2. 全动态标准库链接方式

图 3. 半静态(libgcc,libstdc++) 标准库链接方式

通过上述三图,可以清楚的看到,当用 全静态标准库的链接方式时,所生成的可执行文件最终不依赖任何的动态标准库,而 全动态标准库的链接方式会导致最终应用程序可执行文件依赖于所有用到的标准动态库。

区别于上述两种方式的 半静态链接方式则有针对性的将 libgcc 和 libstdc++ 两个标准库非动态链接。(linux动态库的使用)

(对比 图 2与 图 3,可见在 图 3中这两个标准库的动态依赖不见了)

从实际应用当中发现,最理想的标准库链接方式就是半静态链接,通常会选择将 libgcc 与 libstdc++ 这两个标准库静态链接,从而避免应用程序在不同 Linux 版本间标准库依赖不兼容的问题发生。

维度二 : 最终生成的可执行文件大小(使用 size 命令进行分析)

size 简介:该命令用于显示出可执行文件的大小

涉及语法:size objfile…

其他详细说明请参阅 man 说明。

三种标准库链接方式最终产生的应用程序的可执行文件的大小具体差异见 图 4、图 5、图 6所示:

图 4. 全静态标准库链接方式

图 5. 全动态标准库链接方式

图 6. 半静态(libgcc,libstdc++) 标准库链接方式

通过上述三图可以看出,最终可执行文件的大小随最终所依赖的标准动态库的数量增加而减小。

从实际应用当中发现,最理想的是 半静态链接方式,因为该方式能够在避免应用程序于。

不同 Linux 版本间标准库依赖不兼容的问题发生的同时,使最终生成的可执行文件大小最小化。

示例链接选项中所涉及命令(引用 GCC 原文):

-llibrary

(linux动态库的使用)

-l library:指定所需要的额外库

-Ldir:指定库搜索路径

-static:静态链接所有库

-static-libgcc:静态链接 gcc 库

-static-libstdc++:静态链接 c++ 库

关于上述命令的详细说明,请参阅 GCC 技术手册

Linux 下静态库(archive)的制作方式:

涉及命令:ar

ar 简介:处理创建、修改、提取静态库的操作

涉及选项:

t – 显示静态库的内容

r[ab][f][u] – 更新或增加新文件到静态库中

[s] – 创建文档索引

ar -M [<mri-] – 使用 ar 脚本处理

其他详细说明请参阅 man 说明。

示例情景:

假设现有如 图 7所示两个库文件

图 7. 示例静态库文件

从 图 7中可以得知,CdtLog.a 只包含 CdtLog.o 一个对象文件 , 而 xml.a 包含 TXmlParser.o 和 xmlparser.o 两个对象文件

现将 CdtLog.o 提取出来,然后通过 图 8方式创建一个新的静态库 demo.a,可以看出,demo.a 包含的是 CdtLog.o 以及 xml.a,而不是我们所预期的 CdtLog.o,TXmlParser.o 和 xmlparser.o。这正是区别于 Windows 下静态库的制作。

图 8. 示例静态库制作方式 1

这样的 demo.a 当被链接入某个工程时,所有在 TXmlParser.o 和 xmlparser.o 定义的符号都不会被发现,从而会导致链接错误,提示无法找到对应的符号。显然,通过图 8 方式创建 Linux 静态库是不正确的。

正确的方式有两种:

1.将所有静态库中包含的对象文件提取出来然后重新打包成新的静态库文件。

2.用一种更加灵活的方式创建新的静态库文件:ar 脚本。

显然,方式 1 是比较麻烦的,因为涉及到太多的文件处理,可能还要通过不断创建临时目录用于保存中间文件。

推荐使用如 清单 2 createlib.sh所示的 ar 脚本方式进行创建:

rm demo.a

rm ar.mac

echo CREATE demo.a > ar.mac

echo SAVE >> ar.mac

echo END >> ar.mac

ar -M < ar.mac

ar -q demo.a CdtLog.o

echo OPEN demo.a > ar.mac

echo ADDLIB xml.a >> ar.mac

echo SAVE >> ar.mac

echo END >> ar.mac

ar -M < ar.mac

rm ar.mac

如果想在 Linux makefile 中使用 ar 脚本方式进行静态库的创建,可以编写如 清单 3 BUILD_LIBRARY所示的代码:

清单 3 BUILD_LIBRARY

define BUILD_LIBRARY

$(if $(wildcard $@),@$(RM) $@)

$(if $(wildcard ar.mac),@$(RM) ar.mac)

$(if $(filter %.a, $^),

@ echo CREATE $@ > ar.mac

@ echo SAVE >> ar.mac

@ echo echo END >> ar.mac

@$(AR) -M < ar.mac

)

$(if $(filter %.o,$^),@$(AR) -q $@ $(filter %.o, $^))

$(if $(filter %.a, $^),

@ echo OPEN $@ > ar.mac

$(foreach LIB, $(filter %.a, $^),

@ echo ADDLIB $(LIB) >> ar.mac

)

@ echo SAVE >> ar.mac

@ echo END >> ar.mac

@$(AR) -M < ar.mac

@$(RM) ar.mac

)

endef

$(TargetDir)/$(TargetFileName):$(OBJS)

$(BUILD_LIBRARY)

通过 图 9,我们可以看到,用这种方式产生的 demo.a 才是我们想要的结果。

图 9. 巧妙创建的静态库文件结果

Linux 静态库链接顺序问题及解决方法:

正如 GCC 手册中提到的那样:

It makes a difference where in the command you write this option; the linker

searches and processes libraries and object files in the order they are specified.

Thus, ‘ foo.o -lz bar.o ’ searches library ‘ z ’ after file ‘ foo.o ’ but before

‘ bar.o ’ . If ‘ bar.o ’ refers to functions in ‘ z ’ , those functions may not be loaded.

为了解决这种库链接顺序问题,我们需要增加一些链接选项 :

$(CXX) $(LINKFLAGS) $(OBJS) -Xlinker “-(” $(LIBS) -Xlinker “-)” -o $@

通过将所有需要被链接的静态库放入 -Xlinker “-(” 与 -Xlinker “-)” 之间,可以是 g++ 链接过程中, 自动循环链接所有静态库,从而解决了原本的链接顺序问题。(linux动态库的使用)

涉及链接选项:-Xlinker

-Xlinker option

Pass option as an option to the linker. You can use this to supply system-specific

linker options which GCC does not know how to recognize.

小结

本文介绍了 Linux 下三种标准库链接的方式及各自利弊,同时还介绍了 Linux 下静态库的制作及使用方法,相信能够给 大多数需要部署 Linux 应用程序和编写 Linux Makefile 的工程师提供有用的帮助。返回搜狐,查看更多


一.linux下动态库可以直接运行吗

windows的粻穿纲费蕺渡告杀梗辑dll文件不能直接运行的。linux下的so文件也不能直接运行的;他们都是依赖库,是接口的一种


二.linux动态库和静态库的区别

两者区别:
a,静态库的使用需要:
1 包含一个对应的头文件告知编译器lib文件里面的具体内容
2 设置lib文件允许编译器去查找已经编译好的二进制代码

b,动态库的使用:
程序运行时需要加载动态库,对动态库有依赖性,需要手动加入动态库

c,依赖性:
静态链接表示静态性,在编译链接之后, lib库中需要的资源已经在可执行程序中了, 也就是静态存在,没有依赖性了
动态,就是实时性,在运行的时候载入需要的资源,那么必须在运行的时候提供 需要的 动态库,有依赖性, 运行时候没有找到库就不能运行了

d,区别:
简单讲,静态库就是直接将需要的代码连接进可执行程序;动态库就是在需要调用其中的函数时,根据函数映射表找到该函数然后调入堆栈执行。
做成静态库可执行文件本身比较大,但不必附带动态库
做成动态库可执行文件本身比较小,但需要附带动态库
链接静态库,编译的可执行文件比较大,当然可以用strip命令精简一下(如:strip libtest.a),但还是要比链接动态库的可执行文件大。程序运行时间速度稍微快一点。
静态库是程序运行的时候已经调入内存,不管有没有调用,都会在内存里头。静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。
其在编译程序时若链接,程序运行时会在系统指定的路径下搜索,然后导入内存,程序一般执行时间稍微长一点,但编译的可执行文件比较小;动态库是程序运行的时候需要调用的时候才装入内存,不需要的时候是不会装入内存的。
动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。

动态链接库的特点与优势

首先让我们来看一下,把库函数推迟到程序运行时期载入的好处:

1. 可以实现进程之间的资源共享。

什么概念呢?就是说,某个程序的在运行中要调用某个动态链接库函数的时候,操作系统首先会查看所有正在运行的程序,看在内存里是否已有此库函数的拷贝了。如果有,则让其共享那一个拷贝笭互蒂就郦脚垫协叮茅;只有没有才链接载入。这样的模式虽然会带来一些“动态链接”额外的开销,却大大的节省了系统的内存资源。C的标准库就是动态链接库,也就是说系统中所有运行的程序共享着同一个C标准库的代码段。

2. 将一些程序升级变得简单。用户只需要升级动态链接库,而无需重新编译链接其他原有的代码就可以完成整个程序的升级。Windows 就是一个很好的例子。

3. 甚至可以真正坐到链接载入完全由程序员在程序代码中控制。

程序员在编写程序的时候,可以明确的指明什么时候或者什么情况下,链接载入哪个动态链接库函数。你可以有一个相当大的软件,但每次运行的时候,由于不同的操作需求,只有一小部分程序被载入内存。所有的函数本着“有需求才调入”的原则,于是大大节省了系统资源。比如现在的软件通常都能打开若干种不同类型的文件,这些读写操作通常都用动态链接库来实现。在一次运行当中,一般只有一种类型的文件将会被打开。所以直到程序知道文件的类型以后再载入相应的读写函数,而不是一开始就将所有的读写函数都载入,然后才发觉在整个程序中根本没有用到它们。

静态库:在编译的时候加载生成目标文件,在运行时不用加载库,在运行时对库没有依赖性。
动态库:在目标文件运行时加载,手动加载,且对库有依赖性。

具体在开发中用到哪种库,我觉得还是根据实际的内存大小,ROM大小,运行的速度等综合考虑。...余下全文>>


三.Linux使用ldd命令查看程序调用了哪些动态库

名称 ldd - 打印共享库的依赖关系
大纲 ldd [选项]... 文件...
描述 ldd 输出在命令行上指定的每个程序或共享库需要的共享库。
选项
--version
打印ldd的版本号
-v --verbose
打印所有信息,例如包括符号的版本信息
-d --data-relocs
执行符号重部署,并报告缺少的目标对象(只对ELF格式适用)
-r --function-relocs
对目标对象担肌曹可丨玖查雪肠磨和函数执行重新部署,并报告缺少的目标对象和函数(只对ELF格式适用)
--help 用法信息
或者看看《linux就该这么学》,具体关于这一章地址3w(dot)linuxprobe/chapter-02(dot)html.


四.linux 动态库 有哪些使用方法

对所有用户有效在/etc/profile增加以下内容。只对当前用户有效在Home目录下的
.bashrc或.bash_profile里增加下面的内容:
(注意:等号前面不要加空格,否则可能出现 command not found)
#在PATH中找到可执行文件程序的路径。
export PATH =$PATH:$HOME/bin

#gcc找到头文件的路径
C_INCLUDE_PATH=/usr/include/libxml2:/MyLib
export C_INCLUDE_PATH

#g++找到头文件的路径
CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/usr/include/libxml2:/MyLib
export CPLUS_INCLUDE_PATH

#找到动态链接库的路径
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/MyLib
export LD_LIBRARY_PATH

#找到静态库的路径
LIBRARY_PATH=$LIBRARY_PATH:/MyLib
export LIBRARY_PATH


五.linux c++动态库 调用 c动态库函数

先把.cpp编译成动态库,编译方法:
g++ *.cpp –fPIC –shared –o libtest.so -libyourclib.so
其中,*.cpp表示你的.cpp文件,你可以把它们一一列出,
–fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的,所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
–shared:指明编译成动态库。
libtest.so即为生成的动态库,以lib开头,方怠郸糙肝孬菲茬十长姜便后面使用
-libyourclib.so 是你的c动态库名

编译好之后,就可以来编译你的测试程序了:
gcc test.c -o test -ltest
其中,test是生成的可执行程序
-ltest表示引用生成的动态库libtest.so
大概过程就是这样,你先试一试


六.Linux如何解决动态库的版本控制

3.共享库,小版本升级,即接口不变.
当升级小版本时,共享库的soname 是不变的,所以需要重新把soname 的那个连接文件指定新版本就可以。 调用ldconfig命令,系统会帮你做修改那个soname link文件,并把它指向新的版本呢。这时候你的应用程序就自动升级了。
4.共享库,主版本升级,即接口发生变化。
当升级主版本时,共享库的soname 就会加1.比如libhello.so.0.0.0 变为 libhello.so.1.0.0. 这时候再运行ldconfig 文件,就会发现生成两个连接 文件。
ln -s libhello.so.0----libhello.so.0.0.0
ln -s libhello.so.1-----libhello.so.1.0.0
尽管共享库升级,但是你的程序依旧用的是旧的共享库,并且两个之间不会相互影响。
问题是如果更新的共享库只是增加一些接口,并没有修改已有的接口,也就是向前兼容。但是这时候它的主版本号却增加1. 如果你的应用程序想调用新的共享库,该怎么办? 简单,只要手工把soname 文件修改,使其指向新的版本就可以。(这时候ldconfig 文件不会帮你做这样的事,因为这时候soname 和real name 的版本号主板本号不一致,只能手动修改)。
比如: ln -s libhello.so.0 --- libhello.so.1.0.0
但是有时候,主版本号增加,接口发生变化,可能向前不兼容。这时候再这样子修改,就会报错,“xx”方法找不到之类的错误。
总结一下,Linux 系统是通过共享库的三个不同名字,来管理共享库的多个版本。 real name 就是共享库的实际文件名字,soname 就是共享库加载时的用的文件名。在生成共享库的时候,编译器将soname 绑定到共享库的文件头里,二者关联起来。 在应用程序引用共享库时,其通过link name 来完成,link时将按照系统指定的目录去搜索link名字找到共享库,并将共享库的soname写在应用程序的头文件里。当应用程序加载共享库时,就会通过soname在系统指定的目录(path or LD_LIBRARY)去寻找共享库。
当共享库升级时,分为两种。一种是主板本不变,升级小版本和build 号。在这种情况下,系统会通过更新soname( ldconfig 来维护),来使用新的版本号。这中情况下,旧版本就没有用,可以删掉。
另外一种是主版本升级,其意味着库的接口发生变化,当然,这时候不能覆盖已有的soname。系统通过增加一个soname(ldconfig -p 里面增加一项),使得新旧版本同时存在。原有的应用程序在加载时,还是根据自己头文件的旧soname 去寻找老的库文件。
这是一个trick 的地方。第一系统将会在生成库的时候,就没有soname放到库的头里面。从而应用程序连接时候,就把linkname 放到应用程序依赖库里面。或者换句话说就是,soname这时候不带版本号。 有时候有人直接利用这点来升级应用程序,比如,新版本的库,直接拷贝到系统目录下,就会覆盖掉已经存在的旧的库文件,直接升级。 这个给程序员很大程度的便利性,如果一步小心,就会调到类似windows的Dll hell 陷阱里面。建议不要这样做。
【Note】
1. 指定共享库加载的路径。LD_孩珐粉貉莠股疯瘫弗凯LIBRARY_PATH 优先于 path 环境变量。
2. ldd 可以查看程序,或者共享库依赖的库的路径
3. nm 查看共享库暴露的接口
4. ldc......余下全文>>


七.如何判断linux 动态库调用

创建静态库:
ar -rcs test.a *.o
查看静态库:
ar -tv test.a
解压静态库:
ar -x test.a

查看程序依赖的动态库:
readelf -a xxx|grep library
如:可以看到,下面的交叉程序hello执行依赖于如下两个动态库。
rebi@ubuntu:~/test$ arm-none-linux-gnueabi-readelf -a hello|grep "library"
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED) Shared library: [libc.so.6]肠担斑杆职访办诗暴涧
rebi@ubuntu:~/test$

或者:readelf -l hello 即可。

nm xxx 查看符号
其中,T表示代码段,U表示在其它地方定义,所以需要确保必须在某个.o或库里被定义过。


八.如何让自己的动态链接库文件能够在linux下被调用

  如何让自己的动态链接库文件能够在linux下被调用
  
  VxWorks 安装的DVD有很多自己的动态链接库文件,在启动一些服务的时候需要调用这些动态链接库文件,否则不能启动一些功能,report:找不到相关的库文件。
  
  解决的方法可以有多种:
  
  1. 直接创建软连接的方式,将某动态链接库文件链接到 /lib 或者/usr/lib 下。
  
  ln -s `pwd`/xxx.so /lib/xxx.so
  
  这种方式适合少数固定不变动态链接库文件的调用,但如果文件很多,或者这些文件也是经常存在更新的,这么多比较繁琐。
  
  
  2. 如果直接把动态链接库文件所在的路径直接加到系统查找库的路径下,这里有两种方式:
  
  1) 更改/etc/ld.so.conf, 加入自己的动态链接库路径,好像需要更新/etc/ld.so.cache; 该方法应该可用,没有尝试过。
  
  2) 更改环境变量LD_LIBRARY_PATH,把自己的动态链接库路径,加入到该环境变量中。
  export LD_LIBRARY_PATH=/Jenkins/workspace/Mefa_Nightly_regression_Job02/MAIN/mefa_platform/logs_1st_round/mefaImage&#4尝耽佰甘脂仿拌湿饱溅7;simulatorTools:$LD_LIBRARY_PATH
  在该环境变量中的动态链接库文件会比系统中/lib 或者 /usr/lib 更早调用。
  
  linux重启之后,该环境变量会失效;
  这种方式更适合自动化的测试的需要。


九.如何让linux加载当前目录的动态库

linux 加载当前目录的动态库的方法是:设置合适的环境变量LD_LIBRARY_PATH。
设置方法有以下三种:

1、临时修改,log out之后就失效
在terminal中执行:export LD_LIBRARY_PATH=./

2、让当前帐号以后都优先加载当前目录的动态库
修改~/.bash_profile在文件末尾加上两行: LD_LIBRARY_PATH=./ 和 export LD_LIBRARY_PATH

3、让所有帐号从此都优先加载当前目录的动态库
修改/etc/profile在文件末尾加上两行: LD_LIBRARY_PATH=./ 和 export LD_LIBRARY_PATH

  • linux动态库使用 Linux下动态库和静态库的制作及使用
  • linux动态库 使用 Linux下动态库和静态库的制作及使用
  • linux动态库的使用 Linux下动态库和静态库的制作及使用由美文导刊网(www.eorder.net.cn)收集整理,转载请注明出处!原文地址http://www.eorder.net.cn/pic38855/

    文章评论
    Copyright © 2006 - 2016 www.eorder.net.cn All Rights Reserved
    美文导刊网 版权所有