linux静态库,动态库总结

news2024/10/7 6:48:33

1.介绍

        使用GNU的工具我们如何在Linux下创建自己的程序函数库?一个“程序函数库”简单的说就是一个文件包含了一些编译好的代码和数据,这些编译好的代码和数据可以在事后供其他的程序使用。程序函数库可以使整个程序更加模块化,更容易重新编译,而且更方便升级。  

程序函数库可分为3种类型:静态函数库(static libraries)、共享函数库(shared libraries)、动态加载函数库(dynamically loaded libraries): 

1、静态函数库,是在程序执行前就加入到目标程序中去了 ;

2、动态函数库同共享函数库是一个东西(在linux上叫共享对象库, 文件后缀是.so ,windows上叫动态加载函数库, 文件后缀是.dll)

Linux中命名系统中共享库的规则

2. 静态函数库

        静态函数库实际上就是简单的一个普通的目标文件的集合,一般来说习惯用“.a”作为文件的后缀。可以用ar这个程序来产生静态函数库文件。Ar是archiver的缩写。静态函数库现在已经不在像以前用得那么多了,主要是共享函数库与之相比较有很多的优势的原因。慢慢地,大家都喜欢使用共享函数库了。不过,在一些场所静态函数库仍然在使用,一来是保持一些与以前某些程序的兼容,二来它描述起来也比较简单。 

        静态库函数允许程序员把程序link起来而不用重新编译代码,节省了重新编译代码的时间。不过,在今天这么快速的计算机面前,一般的程序的重新编译也花费不了多少时间,所以这个优势已经不是像它以前那么明显了。静态函数库对开发者来说还是很有用的,例如你想把自己提供的函数给别人使用,但是又想对函数的源代码进行保密,你就可以给别人提供一个静态函数库文件。理论上说,使用ELF格式的静态库函数生成的代码可以比使用共享函数库(或者动态函数库)的程序运行速度上快一些,大概1-5%。 

创建一个静态函数库文件,或者往一个已经存在地静态函数库文件添加新的目标代码,可以用下面的命令: 

        ar rcs my_library.a file1.o file2.o 

这个例子中是把目标代码file1.o和file2.o加入到my_library.a这个函数库文件中,如果my_library.a不存在则创建一个新的文件。在用ar命令创建静态库函数的时候,还有其他一些可以选择的参数,可以参加ar的使用帮助。这里不再赘述。

一旦你创建了一个静态函数库,你可以使用它了。你可以把它作为你编译和连接过程中的一部分用来生成你的可执行代码。如果你用gcc来编译产生可执行代码的话,你可以用“-l”参数来指定这个库函数。你也可以用ld来做,使用它的“-l”和“-L”参数选项。具体用法可以参考info:gcc。 

3. 动态加载的函数库Dynamically Loaded (DL) Libraries

动态加载的函数库Dynamically loaded (DL) libraries是一类函数库,它可以在程序运行过程中的任何时间加载。它们特别适合在函数中加载一些模块和plugin扩展模块的场合,因为它可以在当程序需要某个plugin模块时才动态的加载。例如,Pluggable Authentication Modules(PAM)系统就是用动态加载函数库来使得管理员可以配置和重新配置身份验证信息。

Linux系统下,DL函数库与其他函数库在格式上没有特殊的区别,我们前面提到过,它们创建的时候是标准的object格式。主要的区别就是这些函数库不是在程序链接的时候或者启动的时候加载,而是通过一个API来打开一个函数库,寻找符号表,处理错误和关闭函数库。通常C语言环境下,需要包含这个头文件。 
        Linux中使用的函数和Solaris中一样,都是dlpoen() API。当然不是所有的平台都使用同样的接口,例如HP-UX使用shl_load()机制,而Windows平台用另外的其他的调用接口。如果你的目的是使得你的代码有很强的移植性,你应该使用一些wrapping函数库,这样的wrapping函数库隐藏不同的平台的接口区别。一种方法是使用glibc函数库中的对动态加载模块的支持,它使用一些潜在的动态加载函数库界面使得它们可以夸平台使用。具体可以参考http://developer.gnome.org/doc/API/glib/glib-dynamic-loading-of-modules.html. 另外一个方法是使用libltdl,是GNU libtool的一部分,可以进一步参考CORBA相关资料。  

3.1 dlopen()
dlopen函数打开一个函数库然后为后面的使用做准备。C语言原形是:

        void * dlopen(const char *filename, int flag);

如果文件名filename是以“/”开头,也就是使用绝对路径,那么dlopne就直接使用它,而不去查找某些环境变量或者系统设置的函数库所在的目录了。否则dlopen()就会按照下面的次序查找函数库文件:
1. 环境变量LD_LIBRARY指明的路径。

2. /etc/ld.so.cache中的函数库列表。

3. /lib目录,然后/usr/lib。不过一些很老的a.out的loader则是采用相反的次序,也就是先查 /usr/lib,然后是/lib。
    dlopen()函数中,参数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'。
    如果有好几个函数库,它们之间有一些依赖关系的话,例如X依赖Y,那么你就要先加载那些被依赖的函数。例如先加载Y,然后加载X。

    dlopen()函数的返回值是一个句柄,然后后面的函数就通过使用这个句柄来做进一步的操作。如果打开失败dlopen()就返回一个NULL。如果一个函数库被多次打开,它会返回同样的句柄。 
    如果一个函数库里面有一个输出的函数名字为_init,那么_init就会在dlopen()这个函数返回前被执行。我们可以利用这个函数在我的函数库里面做一些初始化的工作。我们后面会继续讨论这个问题的。  
3.2. dlerror()

通过调用dlerror()函数,我们可以获得最后一次调用dlopen(),dlsym(),或者dlclose()的错误信息。 
3.3. 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()来判断是否出现了错误。一个典型的过程如下:

dlerror();      /*clear error code */  
s = (actual_type)dlsym(handle, symbol_being_searched_for);  
if((error = dlerror()) != NULL){  
    /* handle error, the symbol wasn't found */  
}
else {  
    /* symbol found, its value is in s */  
}  

3.4. dlclose()

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

3.5. DL Library Example

下面是一个例子。例子中调入math函数库,然后打印2.0的余弦函数值。例子中每次都检查是否出错。应该是个不错的范例:

int main(int argc, char *argv){  
        void *handle;  
        char *error;  
          
        double (*cosine )(double);  
        handle = dlopen("/lib/libm.so.6", RTLD_LAZY);  
        if(!handle){  
            fputs(dlerror(), stderr);  
             exit(1);  
        }  
          
        cosine = dlsym(handle, "cos");  
        if((error = dlerror()) != NULL){  
            fputs(error, stderr);  
            exit(1);  
        }  
          
        printf("%f", (*cosine)(2, 0));  
          
        dlclose(handle);  
          
        return 0;  
}  

如果这个程序名字叫foo.c,那么用下面的命令来编译:

     gcc -o foo foo.c –ldl

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/783924.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Spring Cloud】Hystrix熔断机制

文章目录 前言什么是hystrix的熔断?使用hystrix熔断功能的配置Hystrix 工作原理Hystrix工作流 前言 什么是hystrix的熔断? hystrix熔断主要是指在一定的时间窗口内,当请求的次数达到一定的失败比率后,hystrix就会主动拒绝服务&a…

【图像分割】基于浣熊优化算法COA的Otsu(大津法)多阈值电表数字图像分割 电表数字识别【Matlab代码#52】

文章目录 【可更换其他算法,获取资源请见文章第5节:资源获取】1. 原始COA算法1.1 开发阶段1.2 探索阶段 2. 多阈值Otsu原理3. 部分代码展示4. 仿真结果展示5. 资源获取 【可更换其他算法,获取资源请见文章第5节:资源获取】 1. 原始…

长尾式差分放大电路

3.3.2差分放大电路 电路 条件 静态分析 对共模信号的抑制作用 当产生温度变化时,也类似加入了共模信号,由于负反馈电阻 的存在,会产生如下变化。 对差模信号的放大作用 电路 交流等效电路 具体分析 具有恒流源的差分放大电路 电路 详细分析…

STM32 OLED显示汉字及屏幕滚动(I2C协议)

文章目录 一、任务目标二、材料准备硬件:软件: 三、AHT20温湿度传感器的使用四、OLED的使用1.硬件2.字模汉字编码原理取字模 3.工程4.电路连接5.实验效果 五、总结六、参考资料 一、任务目标 理解OLED屏显和汉字点阵编码原理,使用STM32F103的…

Linux下基本指令 -> ls指令

​ Linux - ls 1 简介2 简介3 语法4 常用选项4.1 -a 列出目录下的所有文件,包括以 . 开头的隐含文件4.2 -l 列出文件的详细信息4.3 -d 将目录象文件一样显示,而不是显示其下的文件4.4 -i 输出文件的 i 节点的索引信息4.5 -n 用数字的 UID,GID 代替名称4.…

Qt学习14:Designer设计师

文章首发于我的个人博客:欢迎大佬们来逛逛 Qt项目地址及源码:点击这里 什么是Designer设计师? 简单来说就是通过拖拖拽拽就可以实现窗口上控件的布局。 1. 创建带UI文件的项目 我们在之前的学习中都是不用这个按钮的,现在我们需…

富文本CKEditor5简易入门,包括自定义上传图片(html版+vue.js)

一、安装及引入 官网&#xff1a;https://ckeditor.com/ckeditor-5/download/ 我这边使用的是自定义构建&#xff0c;然后下载下来。 二、简单使用 引入js <script src"../../../assets/plugins/ckeditor5/ckeditor.js"></script>html&#xff1a;…

【PWN · ret2libc】[BJDCTF 2020]babyrop

这题是经典的ret2libc&#xff0c;而且保护开的也不多&#xff0c;实际上&#xff0c;这篇博客的意义更大&#xff1a; 【PWN ret2libc】[2021 鹤城杯]babyof_Mr_Fmnwon的博客-CSDN博客 目录 前言 一、题目 二、思路 三、exp具体编写 总结 前言 简单而纯粹的ret2libc&am…

《DocRED: A Large-Scale Document-Level Relation Extraction Dataset》阅读笔记

引言 近期关注篇章级关系抽取&#xff0c;两个原因&#xff0c;一是之前做大规模知识抽取&#xff0c;遗留的一块内容就是篇章级关系抽取和事件抽取&#xff1b;另一个是大模型目前在抽取任务&#xff0c;特别是复杂抽取任务上表现不如其他NLP任务&#xff0c;这也引起我的研究…

5.2.6.字符设备驱动工作原理1

什么是模块&#xff1f;什么是驱动&#xff1f; 模块 驱动的雏形&#xff0c; 你要能操控硬件才叫驱动 在空的模块的基础上&#xff0c;安装驱动 5.2.6.1、系统整体工作原理 (1)应用层->API->设备驱动->硬件 (2)API&#xff1a;open、read、write、close等 (3)驱动…

20230720今天youtube上的中文字幕自动翻译成为英文的功能失效!

20230720今天youtube上的中文字幕自动翻译成为英文的功能失效&#xff01; 2023/7/20 12:42 &#xff1f;做YouTube挣钱吗&#xff1f; 115网盘 满了。最新 张家界 旅游的视频 放到 youtube就是 60岁/老了的时候的回忆&#xff01; 放到 大陆不保险&#xff01; 如需使用自动翻…

智能合约安全审计

智能合约安全审计的意义 智能合约审计用于整个 DeFi 生态系统&#xff0c;通过对协议代码的深入审查&#xff0c;可以帮助解决识别错误、低效代码以及这些问题。智能合约具有不可篡改的特点&#xff0c;这使得审计成为任何区块链项目安全流程的关键部分。 代码审计对任何应用…

Spring(二):更简单的存储与读取 Bean

通过上一章的Spring&#xff0c;我们基本实现了Spring 的读取与存储&#xff0c;但是在操作过程中&#xff0c;读取与存储并没有那么得“简单” 一套流程还是很复杂&#xff0c;所以&#xff0c;本章来介绍更加简单得读取与存储。 在 Spring 中想要更简单的存储和读取对象的核…

【C++】继承基础知识及简单应用,使用reportSingleClassLayout(在Visual Studio开发人员命令提示窗口)查看派生类详细信息

author&#xff1a;&Carlton tag&#xff1a;C topic&#xff1a;【C】继承基础知识及简单应用&#xff0c;使用reportSingleClassLayout&#xff08;在Visual Studio开发人员命令提示窗口&#xff09;查看派生类详细信息 website&#xff1a;黑马程序员C date&#xf…

MySQL 读写分离

目录 一、什么是读写分离&#xff1f; 二、为什么要读写分离呢&#xff1f; 三、什么时候要读写分离&#xff1f; 四、主从复制与读写分离 五、MySQL 读写分离原理 六、企业 使用MySQL 读写分离场景 1&#xff09;基于程序代码内部实现 2&#xff09;基于中间代理层实现…

比selenium体验更好的ui自动化测试工具: cypress介绍

话说 Cypress is a next generation front end testing tool built for the modern web. And Cypress can test anything that runs in a browser.Cypress consists of a free, open source, locally installed Test Runner and a Dashboard Service for recording your tests.…

【yolov7】训练自己的数据集-实践笔记

【yolov7】训练自己的数据集-实践笔记 使用yolov7训练自己的数据集&#xff0c;以RSOD数据集为例&#xff0c;图像数量976&#xff0c;一共四类。 yolov7源码&#xff1a;https://github.com/WongKinYiu/yolov7 同时在该网址下载好预训练文件&#xff0c;直接放到yolov7-main…

【每日随笔】马太效应 ② ( 马太效应因果分析 | 规模效应 | 齿轮效应 | 资源优势 | 抗风险能力 | 领先效应 )

文章目录 一、规模效应二、齿轮效应三、资源优势四、抗风险能力五、领先效应 在本文中 , 分析马太效应产生的原因 ; 一、规模效应 自然界中的规模效应 : 体型庞大的动物 , 如 大象 , 犀牛 , 雄狮 , 河马 , 很少被弱小的动物击败 , 都是自然死亡 , 老死 , 病死 , 同类厮杀 ; 经济…

多源BFS-- 矩阵距离

关于多源BFS&#xff0c;基本上就是单源BFS的简单升级了一下&#xff0c;比如在queue中队头开始时只有一个&#xff0c;我们通过这一个队头去推导其他的东西。而多源最短路就是队头一开始有1-n个可能的数&#xff0c;一个一个去BFS。 题目思路&#xff1a; 这个题就直接把所有的…

苹果开发“Apple GPT”AI科技迎来新格局

根据彭博社的马克・古尔曼&#xff08;Mark Gurman&#xff09;报道&#xff0c;苹果内部正在开发“Apple GPT”人工智能项目&#xff0c;足以媲美 OpenAI 的 ChatGPT &#xff0c;预计明年推出。就在彭博社消息发出之后&#xff0c;苹果股价上涨了2.3%&#xff0c;市值顶峰时增…