dlopen linux 实例_Linux静态库和动态库

ac647b3730e864fb56c49fcca5c4e873.png

库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行。库分静态库和动态库两种。

静态库和动态库的区别

1. 静态函数库

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

2. 动态函数库

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

静态库的使用

静态库的操作工具:gcc和ar 命令。

编写及使用静态库

(1)设计库源码 pr1.c 和 pr2.c

[root@billstone make_lib]# cat pr1.c

void print1()

{

printf("This is the first lib src!n");

}

[root@billstone make_lib]# cat pr2.c

void print2()

{

printf("This is the second src lib!n");

}

(2) 编译.c 文件

[bill@billstone make_lib]$ cc -O -c pr1.c pr2.c

[bill@billstone make_lib]$ ls -l pr*.o

-rw-rw-r-- 1 bill bill 804 4 月 15 11:11 pr1.o

-rw-rw-r-- 1 bill bill 804 4 月 15 11:11 pr2.o

(3) 链接静态库

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

[bill@billstone make_lib]$ ar -rsv libpr.a pr1.o pr2.o

a - pr1.o

a - pr2.o

[bill@billstone make_lib]$ ls -l *.a

-rw-rw-r-- 1 bill bill 1822 4 月 15 11:12 libpr.a

[bill@billstone make_lib]$ ar -t libpr.a

pr1.o

pr2.o

(4) 调用库函数代码 main.c

[bill@billstone make_lib]$ cat main.c

int main()

{

print1();

print2();

return 0;

}

(5) 编译链接选项

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

[bill@billstone make_lib]$ gcc -o main main.c -L./ -lpr

[bill@billstone make_lib]$ ls -l main*

-rwxrwxr-x 1 bill bill 11805 4 月 15 11:17 main

-rw-rw-r-- 1 bill bill 50 4 月 15 11:15 main.c

(6)执行目标程序

[bill@billstone make_lib]$ ./main

This is the first lib src!

This is the second src lib!

[bill@billstone make_lib]$

动态库的使用

编写动态库

(1)设计库代码

[bill@billstone make_lib]$ cat pr1.c

int p = 2;

void print(){

printf("This is the first dll src!n");

}

[bill@billstone make_lib]$

(2)生成动态库

[bill@billstone make_lib]$ gcc -O -fpic -shared -o dl.so pr1.c

[bill@billstone make_lib]$ ls -l *.so

-rwxrwxr-x 1 bill bill 6592 4 月 15 15:19 dl.so

[bill@billstone make_lib]$

动态库的隐式调用

在编译调用库函数代码时指明动态库的位置及名字, 看下面实例

[bill@billstone make_lib]$ cat main.c

int main()

{

print();

return 0;

}

[bill@billstone make_lib]$ gcc -o tdl main.c ./dl.so

[bill@billstone make_lib]$ ./tdl

This is the first dll src!

[bill@billstone make_lib]$

当动态库的位置活名字发生改变时, 程序将无法正常运行; 而动态库取代静态库的好处之一则是通过更新动态库而随时升级库的内容.

动态库的显式调用

显式调用动态库需要四个函数的支持, 函数 dlopen 打开动态库, 函数 dlsym 获取动态库中对象基址, 函数 dlerror 获取显式动态库操作中的错误信息, 函数 doclose 关闭动态库.

[bill@billstone make_lib]$ cat main.c

#include <dlfcn.h>

int main()

{

void *pHandle;

void (*pFunc)(); // 指向函数的指针

int *p;

pHandle = dlopen("./d1.so", RTLD_NOW); // 打开动态库

if(!pHandle){

printf("Can't find d1.so n");

exit(1);

}

pFunc = (void (*)())dlsym(pHandle, "print"); // 获取库函数 print 的地址

if(pFunc)

pFunc();

else

printf("Can't find function printn");

p = (int *)dlsym(pHandle, "p"); // 获取库变量 p 的地址

if(p)

printf("p = %dn", *p);

else

printf("Can't find int pn");

dlclose(pHandle); // 关闭动态库

return 0;

}

[bill@billstone make_lib]$ gcc -o tds main.c –ld1 –L.

此时还不能立即./tds,因为在动态函数库使用时,会查找/usr/lib、/lib目录下的动态函数库,而此时我们生成的库不在里边。 这个时候有好几种方法可以让他成功运行: 最直接最简单的方法就是把libstr_out.so拉到/usr/lib或/lib中去。 还有一种方法 export LD_LIBRARY_PATH=$(pwd) 另外还可以在/etc/ld.so.conf文件里加入我们生成的库的目录,然后/sbin/ldconfig。 /etc/ld.so.conf是非常重要的一个目录,里面存放的是链接器和加载器搜索共享库时要检查的目录,默认是从/usr/lib /lib中读取的,所以想要顺利运行,我们也可以把我们库的目录加入到这个文件中并执行/sbin/ldconfig 。另外还有个文件需要了解/etc/ld.so.cache,里面保存了常用的动态函数库,且会先把他们加载到内存中,因为内存的访问速度远远大于硬盘的访问速度,这样可以提高软件加载动态函数库的速度了。

库依赖的查看

使用ldd命令来查看执行文件依赖于哪些库。

该命令用于判断某个可执行的 binary 档案含有什么动态函式库。
[root@test root]# ldd [-vdr] [filename]
参数说明:
--version  打印ldd的版本号
-v --verbose  打印所有信息,例如包括符号的版本信息
-d --data-relocs  执行符号重部署,并报告缺少的目标对象(只对ELF格式适用)
-r --function-relocs  对目标对象和函数执行重新部署,并报告缺少的目标对象和函数(只对ELF格式适用)
--help 用法信息。

如果命令行中给定的库名字包含'/',这个程序的libc5版本将使用它作为库名字;否则它将在标准位置搜索库。运行一个当前目录下的共享库,加前缀"./"。

Linux-C语言学习交流群【721709245】在学的进群一起交流,资料自己群文件下载

相关资料:

Linux库的实现与应用:

静态库

动态库

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

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

相关文章

反射setaccessible_advancedday16类加载器,反射

加载配置文件在src目录下创建一个config.properties配置文件&#xff0c;使用类加载器加载配置文件。//创建集合Properties propertiesnew Properties();//获取src目录下&#xff0c;配置文件的流InputStream in ClassLoader.getSystemClassLoader() .getResourceAsStream(…

基于matlab的语音信号,科学网—[转载]【信息技术】【2014.06】【含源码】基于MATLAB的语音信号处理与分析 - 刘春静的博文...

本文为瑞典耶夫勒大学(作者&#xff1a;Nan Wu)的学士论文&#xff0c;共48页。语音传递是人类最重要、最有效、最常用的信息交流方式。语言是人类特有的特征&#xff0c;而人声是常用的工具&#xff0c;也是相互传递信息的重要途径。语音具有较大的信息容量。因此&#xff0c;…

string.intern_使用String.intern()减少内存使用

string.intern时不时地会有一个垂死的生产应用程序。 而且您知道您需要尽快对其进行修补。 我们也是如此&#xff0c;并认为分享最近的一个战争故事会很有趣。 在这种情况下&#xff0c;我们就有机会使用String.intern&#xff08;&#xff09;之类的简单补丁来修补应用程序。 …

微信批量退款php,微信支付退款接口详解

微信支付有2个退款相关的接口&#xff0c;分别是申请退款API和查询退款API&#xff0c;这2个接口在实际微信支付开发中都会用到。其中申请退款API因为安全性&#xff0c;需要使用证书&#xff0c;证书在商户平台后台下载.申请退款接口支持一年以内的订单退款&#xff0c;可以分…

1235813找规律第100个数_人教版一年级下册数学第1-8单元知识点梳理填空,附答案...

参考答案&#xff1a;第一单元 认识图形1、认识平面图形 2、平面图形的拼组用相同的正方形、长方形或三角形可以分别拼成更大的正方形、长方形或三角形。3、认识七巧板 七巧板是由1个正方形、1个平行四边形、5个三角形组成的。第二单元 20以内的退位减法1、十几减几的计算方法(…

pandas整表写入excel指定位置_当Python遇到Excel,一个能打的都没有~

几乎人人都在用Excel&#xff0c;这种极易上手的数据分析工具无处不在&#xff0c;一旦你掌握了窍门&#xff0c;它就变得非常强大。而Python通常被认为更具有挑战性&#xff0c;但能做的事也更多。当Python遇到Excel会发生什么&#xff1f;本文将告诉你&#xff0c;这三项Exce…

无需再忙了:Lambda-S3缩略图,由SLAppForge Sigma钉牢!

如果你还没有注意到了&#xff0c;我最近被唠叨试图开始使用时&#xff0c;我遭遇了陷阱AWSλ-S3正式例子 。 虽然大多数这些愚蠢的错误的指责是对我自己的懒惰&#xff0c;过度自尊和缺乏对细节的关注&#xff0c;我个人觉得&#xff0c;在开始与一家领先的无服务器供应商不应…

sqlyog设置自动补全_Visual Studio Code 最好的功能、插件和设置

Visual Studio Code 是由 Microsoft(微软) 发布的一个免费的&#xff0c;开源的跨平台文本编辑器。他们基于在线编辑 Visual Studio Online (代号为 “Monaco”)&#xff0c;并结合 GitHub 的 Electron 实现的一个跨平台编辑器。他们在为程序员创建一个快速且高效工作环境方面取…

ejb 示例 2018_Java EE EJB拦截器教程和示例

ejb 示例 2018在此示例中&#xff0c;我们将看到如何在EJB中使用拦截器并使用简单的Web应用程序对其进行测试。 1.简介 顾名思义&#xff0c;当您想拦截对EJB方法的调用时&#xff0c;将使用拦截器。 如果为Bean声明一个拦截器&#xff0c;则每次调用该Bean的方法时&#xff0…

linux怎么使用串口线,如何在Linux下使用USB转串口线,鼎力告诉您

亲爱的朋友&#xff0c;如果您使用的Linux的系统&#xff0c;应该怎么来使用我们的鼎力的USB转串口线呢&#xff1f;下面就来告诉您吧&#xff01;用Linux&#xff0c;不需要另外安装USB转串口驱动!前提是你要先安装minicom输入命令&#xff1a;dmesg| grep usb&#xff0c;看到…

comsol分析时总位移代表什么_超弹性材料模型的压缩分析

为了表征超弹性材料&#xff0c;需要进行各种测试获取实验数据&#xff0c;包括承受单轴拉伸和压缩、双轴拉伸和压缩以及扭转测试。今天&#xff0c;我们向大家介绍如何使用通过单轴和双轴测试获得的拉伸和压缩测试数据&#xff0c;模拟由弹性泡沫材料制成的球体的压缩。通过案…

由对称性知定点一定在x轴上_线上优秀教学案例(九)|计算机科学与工程学院刘钊:“延期不延教”之“1+X课堂”...

【编者按】受新冠肺炎疫情影响&#xff0c;按照教育部和河北省教育厅统一部署&#xff0c;学校延迟春季开学时间。为最大程度减少疫情和延期开学对我校教育教学工作的影响&#xff0c;本学期&#xff0c;我校以线上教学的形式拉开序幕。面对新的教学模式&#xff0c;各学院、广…

和显卡驱动要配套吗_天天学渲染,你的显卡驱动用对了吗?

大家好&#xff0c;最近一直有很多人和我反馈说&#xff0c;自己在使用Octane或者Redshift渲染器渲染的时候经常容易崩溃&#xff0c;甚至是闪退了&#xff0c;其实这个问题有很大一部分原因是由于你的显卡驱动没用对导致的。接下来就和大家说下如何解决。首先我们大部分人买了…

网络研讨会:Java 9的第一印象–构建可伸缩企业应用程序的新方法

在此网络研讨会上听我们对新Java版本的一些初步想法 Java 9的新版本引起了很多炒作。在Mark Reinhold领导的专门团队的带领下&#xff0c;将Java平台迁移到模块花费了近十年的辛苦工作。 除了备受期待的Project Jigsaw&#xff0c;此版本还包含许多其他令人兴奋的功能。 现在是…

noj数据结构稀疏矩阵的加法十字链表_一个算法毁了一款好游戏?算法和数据结构到底有多重要?...

来源 | 异步前段时间大火的国产游戏——《太吾绘卷》&#xff0c;由于创新的玩法和精良的制作一度广受好评&#xff0c;然而随着玩家游戏的深入和时长的积累&#xff0c;发现该游戏在玩的过程中游戏外的问题很多很多。首先是存档速度慢&#xff0c;然后是密集的计算导致功耗大量…

arm-linux-gcc libstdc .so.6,mini2440编译内核:usr/lib/libstdc++.so.6 not found

买了块mini2440开发板&#xff0c;按照光盘中的mini2440用户手册编译内核时&#xff0c;#make zImage出现错误&#xff1a;usr/lib/libstdc.so.6 not found&#xff0c;在网上百度了下&#xff0c;有很多不同的解决办法&#xff0c;我试了一个&#xff0c;编译成功 ^ ^注&#…

前端实现可绘制的canvas画布_前端图形学基础(五)——Canvas状态管理

点击右上角的关注&#xff0c;不定期前端干货分享&#xff01;&#xff01;欢迎来到我的前端图形学系列文章&#xff1a;前端图形学基础(一)——Canvas基础入门前端图形学基础(二)——Canvas基础前端图形学基础(三)——Canvas绘制图片前端图形学基础(四)——Canvas绘制曲线我们…

having和where可以同时使用吗_阴、阳离子聚丙烯酰胺可以同时混合溶解使用吗?...

聚丙烯酰胺是一种水处理药剂&#xff0c;需要溶解在水中制成浓度为0.1%-0.5%的聚丙烯酰胺水溶液。一般来说&#xff0c;当聚丙烯酰胺实际使用时&#xff0c;阴离子聚丙烯酰胺和阳离子聚丙烯酰胺可以同时使用。但是&#xff0c;阳离子聚丙烯酰胺和阴离子聚丙烯酰胺不能混合在一起…

Lombok,AutoValue和Immutables,或如何编写更少,更好的代码返回

在上一篇有关Lombok库的文章中 &#xff0c;我描述了一个库&#xff0c;该库有助于处理Java中的样板代码&#xff08; 是的&#xff0c;我知道这些问题已经在Kotlin中解决了 &#xff0c;但这是现实生活&#xff0c;我们不能一味地坐下来&#xff0c;一旦出现较新或更简单的语言…

福州PHP讲师招聘_“艺”起就业|招聘信息汇总

亲爱的美术学院毕业生们在全国上下万众一心抗击新冠肺炎疫情的关键时期学院党委高度重视并时刻关注着每一位毕业生的就业工作为进一步做好疫情防控工作也为进一步确保同学们顺利求职就业保障毕业生就业工作的时效性学院公众号特别设立“艺”起就业—招聘信息发布栏目 由院学工…