你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

讨论linux下的库

[复制链接]
gaosmile 发布时间:2020-11-20 20:02
[导读]本文仅讨论linux下的库。




一口君中学阶段最喜欢的一首歌。

窦仙才华横溢、潇洒不羁、与世无争,酷的外焦里嫩!

让我们随着窦仙高昂的声音来学习什么是(酷)库吧!

一、什么是库?

在windows平台和linux平台下都大量存在着库。一般是软件作者为了发布方便、替换方便或二次开发目的,而发布的一组可以单独与应用程序进行compile time或runtime链接的二进制可重定位目标码文件。

本质上来说库是一种可执行代码的二进制形式,这个文件可以在编译时由编译器直接链接到可执行程序中,也可以在运行时由操作系统的runtime enviroment根据需要动态加载到内存中。

一组库,就形成了一个发布包,当然,具体发布多少个库,完全由库提供商自己决定。

由于windows和linux的本质不同,因此二者库的二进制是不兼容的。

现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。

共享库的好处是,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。

本文仅讨论linux下的库。

二、库的分类

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

win32平台下,静态库通常后缀为.lib,动态库为.dll]int add(int x,int y)
{
     return x+y;
}
int sub(int x,int y)
{
     return x-y;
}

add.h

<span]<span]gcc -c add.c
  • 使用 ar 命令生成静态库libadd.a
ar]#include
#include "add.h"
void main()
{
    printf("add(5,4) is %d\n",add(5,4));
    printf("sub(5,4) is %d\n",sub(5,4));
}

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

gcc]gcc -c -I /home/xxxx/include test.c //假设test.c要使用对应的静态库
gcc -o test -L /home/xxxxx/lib test.o libadd.a

或者

gcc]gcc -fPIC -o libadd.o -c add.c
gcc -shared -o libadd.so libadd.o

也可以直接使用一条命令

gcc]sudo cp libadd.so /lib
  • 使用动态库
<span]<span]gcc static -o run  -ladd

注意观察编译时动态库的名字与库文件对应关系

libadd.so<--------->-ladd
[p=26,]libadd.so<--------->-ladd
[p=26,]
void * dlopen(const char *filename, int flag);
参数

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的意思是resolve undefined symbols as code from the dynamic library is executed,而RTLD_NOW的含义是resolve all undefined symbols before dlopen() returns and fail if this cannot be done'。
返回值
dlopen()函数的返回值是一个句柄,然后后面的函数就通过使用这个句柄来做进一步的操作。如果打开失败dlopen()就返回一个NULL。如果一个函数库被多次打开,它会返回同样的句柄。

如果有好几个函数库,它们之间有一些依赖关系的话,例如X依赖Y,那么你就要先加载那些被依赖的函数。例如先加载Y,然后加载X。

dlerror()

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

dlsym()

如果你加载了一个DL函数库而不去使用当然是不可能的了,使用一个DL函数库的最主要的一个函数就是dlsym(),这个函数在一个已经打开的函数库里面查找给定的符号。这个函数如下定义:

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

dlclose()

dlopen()函数的反过程就是dlclose()函数,dlclose()函数用力关闭一个DL函数库。Dl函数库维持一个资源利用的计数器,当调用dlclose的时候,就把这个计数器的计数减一,如果计数器为0,则真正的释放掉。真正释放的时候,如果函数库里面有_fini()这个函数,则自动调用_fini()这个函数,做一些必要的处理。Dlclose()返回0表示成功,其他非0值表示错误。

举例

<span]<span] vi /etc/profile

在文件里末尾加上对应的环境变量信息。

动态库环境变量设置:

<span]<span]source /etc/profile
3./etc/ld.so.conf

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

vim]/usr/local/lib/

运行ldconfig,该命令会重建/etc/ld.so.cache文件

七、常见库的移植1.jpeg库,用于jpeg图像处理

下载地址:

http://www.ijg.org/files/

解压

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

编译,   安装

] mkdir -p /home/peng/jpeg-6b/temp_install/include
mkdir -p /home/peng/jpeg-6b/temp_install/lib
mkdir -p /home/peng/jpeg-6b/temp_install/man/man1  




收藏 评论0 发布时间:2020-11-20 20:02

举报

0个回答

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版