ld是什么意思(ld是什么意思在微信里边)

1.什么是图书馆?windows和linux平台上都有很多库。它是通用软件作者为方便发布、替换或二次开发而发布的一组二进制可重定位目标代码文件,可以在编译时或运

1.什么是图书馆?

ld是什么意思(ld是什么意思在微信里边)插图

windows和linux平台上都有很多库。它是通用软件作者为方便发布、替换或二次开发而发布的一组二进制可重定位目标代码文件,可以在编译时或运行时独立地与应用程序链接。

本质上,库是可执行代码的二进制形式。该文件可以在编译时由编译器直接链接到可执行程序,或者根据需要在运行时由操作系统的运行时环境动态加载到内存中。

一组库形成一个分发包。当然,发布多少库完全由库提供者决定。

因为windows和linux的本质不同,所以两个库的二进制文件是不兼容的。

现实中,每个程序都依赖于很多基础底层库,不可能每个人的代码都是从零开始的,所以库的存在意义非同一般。

共享库的优点是,如果不同的应用程序调用同一个库,那么只有一个共享库的实例需要在内存中。

本文只讨论linux下的库。

二、图书馆的分类

有两种库:静态库和共享库(动态库)。

win32平台下,静态库通常后缀为.lib,动态库为.dll;linux平台下,静态库通常后缀为.a,动态库为.so。

本质上,同一个程序编译的静态库和动态库在功能上没有区别。区别只在于它的名字,即“静态”和“动态”。

两者都是以文件的形式存在,本质上是可执行代码的二进制格式,可以加载到内存中执行。无论是动态链接库还是静态链接库,它们只是向自己的调用者提供变量、函数和类。

1.静态库

所谓静态库,就是编译器在静态编译时搜索并链接到指定的目录。一旦链接完成,最终的可执行程序就包含了库文件中所有有用的信息,包括代码段、数据段等。

2.动态图书馆

所谓动态库,就是应用程序运行时,操作系统根据应用程序的请求,动态搜索指定目录并加载到内存中,同时需要地址重定向。

3.差异

我们通过编译链接和加载时间来讨论静态库和动态库的区别。

编译链接

程序编译时静态链接库会链接到目标代码,目标程序运行时不再需要更改动态库。移植方便,体积大,浪费空空间和资源,因为所有相关的对象文件和相关的库都链接起来形成一个可执行文件,导致可执行文件的体积很大。

动态库在程序编译时不链接目标代码,而是在程序运行时加载,因为可执行文件很小。有了动态库,程序升级会相对简单。例如,如果升级动态库,只需要替换该动态库的文件,而不是可执行文件。然而,应该注意,可执行程序需要能够在运行时找到动态库文件。可执行文件时动态库的调用者。

程序代码和库程序和库

负载力矩

两者的区别在于加载代码的时间不同。静态库的代码在编译过程中已经加载到可执行程序中,所以体积较大。共享库代码只在可执行程序运行时才加载到内存中,在编译过程中简单引用,所以代码量小。

4.优点和缺点

与动态库相比,静态库的优点是直接链接到可执行程序中。之后,可执行程序就不再依赖于运行环境的设置(当然还是依赖于CPU指令集、操作系统支持的可执行文件格式等硬限制)。

动态库的好处是用户甚至可以在程序运行的时候随时替换它,这就构成了动态插件系统的基础。使用具体的静态库和动态库,由程序员根据需要决定。

另外需要注意的是,从底层实现来看,动态库的效率可能比静态库稍差。注意,这里用的是“可能”这个词,具体与否取决于写程序的人。主要原因是程序不能直接调用动态库中的函数符号,只能通过调用操作系统的运行时环境接口来动态加载某个函数符号,同时获取该函数符号在内存中的地址并保存为函数指针进行调用,这就在调用函数时增加了一个间接寻址过程。

第三,图书馆文献的生产1.库文件的命名

静态库的名字一般是libxxxx.a,其中xxxx是库的名字;动态库的名称一般为libxxxx.so.x.y.z,其含义如下图所示:

2.制作库文件的常用参数

首先,了解gcc编译器使用的一些参数很重要。

参数含义-shared指定生成动态链接库。-static指定生成静态链接库。-fPIC表示编译为与位置无关的代码,用于编译共享库。对象需要被创建为独立于位置的代码。从概念上讲,当可执行程序加载它们时,它们可以放在可执行程序内存中的任何地方。-L表示要连接的库在当前目录中。-l指定链接时所需的动态库。编译器在寻找动态链接库时有一个隐式的命名规则,即在给定的名称和之前添加lib。所以在它确定了图书馆的名称之后。-Wall生成所有警告消息。-ggdb这个选项会尽可能的生成gdb可用的调试信息。-g编译器在编译时生成调试信息。-c只激活预处理、编译和汇编,即使程序成为一个目标文件(。o文件)。-Wl,options将参数(选项)传递给链接器ld。如果选项中间有逗号,就把选项分成多个选项,传递给链接器。

3.库源文件

假设我们想将以下两个文件放入库文件add.c中

intadd(intx,inty){returnx+y;}intsub(intx,inty){returnx-y;}

add.h

intadd(intx,inty);intsub(intx,inty);4.制作一个静态库并使用它需要把 add.c 编译成.o文件gcc-cadd.c使用 ar 命令生成静态库libadd.aar-rclibadd.aadd.o遵循静态库命名的规则lib+名字+.a使用静态库 要是用静态库libadd.a,只需要包含add.h,就可以使用函数add()、sub()。#include<stdio.h>#include"add.h"voidmain(){printf("add(5,4)is%d\n",add(5,4));printf("sub(5,4)is%d\n",sub(5,4));}

静态库的文件可以放在任何位置,编译时只需要找到库文件。

gcctest.c-orunlibadd.a库和头文件如果在其他目录下

使用以下命令进行编译:

gcc-c-I/home/xxxx/includetest.c//假设test.c要使用对应的静态库gcc-otest-L/home/xxxxx/libtest.olibadd.a

或者

gcc-c-I/home/xxxx/include-L/home/xxxxx/liblibadd.atest.c

1).通过-I(大I)指定对应的头文件。2).使库文件的路径通过-L,libadd.a是要使用的静态库。3).静态库的头文件应该包含在test.c中

5.制作一个动态库并使用它把add.c编译成动态链接库libadd.sogcc-fPIC-olibadd.o-cadd.cgcc-shared-olibadd.solibadd.o

您也可以直接使用命令。

gcc-fPIC-shared-olibadd.soadd.c动态库的安装 通常动态库拷贝到/lib下即可:sudocplibadd.so/lib使用动态库#include<stdio.h>#include"add.h"voidmain(){printf("add(5,4)is%d\n",add(5,4));printf("sub(5,4)is%d\n",sub(5,4));}

编译动态库:

gccstatic-orun-ladd

在编译时观察动态库和库文件的名称之间的对应关系。

libadd.so<--------->-ladd

移除。于是,lib简化为L,其他字母保留。

6.动态加载库(DL)库

动态加载函数库是一种函数库,可以在程序运行过程中随时加载。它们特别适合加载函数中的一些模块和插件扩展模块,因为它们可以在程序需要插件模块时动态加载。

在Linux系统下,DL函数库和其他函数库在格式上没有特别的区别。当它们被创建时,它们是标准的对象格式。主要区别是程序链接或启动时不加载这些函数库,而是用一个API打开一个函数库,找到符号表,处理错误,关闭函数库。通常在C语言环境下,需要包含这个头文件。

dlopen()

dlopen函数打开一个函数库,准备以后使用。c语言的原型是:

void*dlopen(constchar*filename,intflag);参数filename如果文件名filename是以“/”开头,也就是使用绝对路径,那么dlopne就直接使用它,而不去查找某些环境变量或者系统设置的函数库所在的目录了。否则dlopen()就会按照下面的次序查找函数库文件:1.环境变量LD_LIBRARY指明的路径。2./etc/ld.so.cache中的函数库列表。3./lib目录,然后/usr/lib。一些很老的a.out的loader则是采用相反的次序,也就是先查/usr/lib,然后是/lib。flag的值必须是RTLD_LAZY或者RTLD_NOW,RTLD_LAZY的意思是resolveundefinedsymbolsascodefromthedynamiclibraryisexecuted,而RTLD_NOW的含义是resolveallundefinedsymbolsbeforedlopen()returnsandfailifthiscannotbedone'。返回值dlopen()函数的返回值是一个句柄,然后后面的函数就通过使用这个句柄来做进一步的操作。如果打开失败dlopen()就返回一个NULL。如果一个函数库被多次打开,它会返回同样的句柄。

如果有几个函数库,并且它们之间有一些依赖关系,比如X依赖Y,那么你要先加载那些依赖函数。比如先加载y,再加载x。

错误()

通过调用dlerror()函数,我们可以获得最后一次调用dlopen()、dlsym()或dlclose()的错误消息。

dlsym()

如果加载一个DL库而不使用,当然是不可能的。使用DL库最重要的函数是dlsym(),它在打开的库中查找给定的符号。该功能定义如下:

void*dlsym(void*handle,char*symbol);参数handle就是由dlopen打开后返回的句柄,symbol是一个以NIL结尾的字符串。功能:如果dlsym()函数没有找到需要查找的symbol,则返回NULL。如果你知道某个symbol的值不可能是NULL或者0,那么就很好,你就可以根据这个返回结果判断查找的symbol是否存在了;不过,如果某个symbol的值就是NULL,那么这个判断就有问题了。标准的判断方法是先调用dlerror(),清除以前可能存在的错误,然后调用dlsym()来访问一个symbol,然后再调用dlerror()来判断是否出现了错误。

dlclose()

dlopen()函数的反向过程是dlclose()函数,强制关闭一个DL函数库。Dl函数库维护了一个资源利用计数器。当调用dlclose时,此计数器的计数减1。如果计数器为0,则真的释放。释放时,如果函数库中有function _fini(),会自动调用function _fini()做一些必要的处理。Dlclose()返回0表示成功,其他非零值表示错误。

举个例子

#include<stdio.h>#include<dlfcn.h>voidmain(){int(*add)(intx,inty);int(*sub)(intx,inty);void*libptr;libptr=dlopen("./libadd.so",RTLD_LAZY);//加载动态库add=dlsym(libptr,"add");//获取函数地址sub=dlsym(libptr,"sub");printf("add(5,4)is%d\n",add(5,4));printf("sub(5,4)is%d\n",sub(5,4));dlclose(libptr);}四、两个查看库的命令查看依赖库命令ldd

使用ldd命令查看可执行程序所依赖的库。

这个命令非常有用。在实际工作中,总是有各种各样的库,有些程序的执行依赖于几个库。各种库的版本历史版本很多,经常导致库不兼容。我们需要根据实际情况适当减少或升级版本。

例如:

可以看到线程库libpthread-2.23.so依赖于libc库和ld-linux库。

nm

Nm工具可以打印交货中涉及的所有符号。这是我们创建的动态库libadd.a的视图:

nm纳米

动词 (verb的缩写)图书馆的安装

有几种方法可以让系统在新安装后找到新的库:

1.复制到/lib或/usr/lib。

如果安装在/lib或者/usr/lib下,那么默认可以找到ld,不需要任何其他操作。如果您将它安装在另一个目录中,您需要将它添加到/etc/ld.so.cache文件中,如下所示

2.通过配置文件/etc/profile

永久环境变量设置,只需编辑/etc/profile即可。

vi/etc/profile

在文件末尾添加相应的环境变量信息。

动态库环境变量设置:

exportLD_LIBRARY_PATH=/home/peng/mylib/

/home/peng/mylib/指的是动态库文件夹的位置。也就是说,文件如。/home/peng/mylib/下也是。

完成编辑,保存编辑并退出;使配置立即生效:

source/etc/profile3./etc/ld.so.conf

编辑/etc/ld.so.conf文件,并添加库文件所在目录的路径。

vim/etc/ld.so.conf

只需添加动态库所在的路径,例如

/usr/local/lib/

运行ldconfig,这将重建/etc/ld.so.cache文件。

七、常见的库移植jpeg图像处理jpeg图书馆

下载地址:

解压

tarxvzfjpegsrc.v6b.tar.gzcdjpeg-6b

生成Makefile

./configure--host=arm-linux-gnueabihf--prefix=$PWD/temp_install

编译、安装

makemakeinstall

注意这个库的安装程序有bug,发布的lib,include,man等也有bug。不会自动创建,所以要手动创建,或者做好其他库再安装这个库。

mkdir-p/home/peng/jpeg-6b/temp_install/includemkdir-p/home/peng/jpeg-6b/temp_install/libmkdir-p/home/peng/jpeg-6b/temp_install/man/man1

更多Linux知识,请关注一口Linux。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。

作者:美站资讯,如若转载,请注明出处:https://www.meizw.com/n/131706.html

发表回复

登录后才能评论