首页 > 其他分享 >静态库、动态库比较与制作

静态库、动态库比较与制作

时间:2024-03-24 16:57:28浏览次数:21  
标签:静态 ELF so 动态 制作 库函数

目录

静态库、动态库比较与制作

静态库与动态库比较

  • 文件名:在unix中静态库一般以.a结尾,动态库一般以.so结尾

  • 静态库:静态库和源码一起被打包到最终的可执行文件(ELF),节约了编译时间,最后得到的可执行文件体积大,但是速度快

  • 动态库:动态库不和源码一起被打包,执行到库函数时会去动态寻找调用动态库中的库函数,可执行文件体积小,但是速度慢(现在二者速度差异减少)

静态库

制作方法

要制作一个静态库,或将目标代码加入到已存在的静态库中,可以使用以下命令:

ar rcs libmylib.a file1.o
  1. 准备好源码对应的目标.o文件

image

  1. 制作静态库

ar rcs libmymath.a add.o div1.o sub.o

得到libmymath.a静态库,一个ar架构的文件

image

如何使用

一般的,制作好的动态库必须与对应的头文件一起提供者给开发者

image

将目标代码与静态库一起编译到一起使用:

gcc main.c libmymath.a -o main

生成ELF文件正常使用,生成的文件大小相对较大:

image

动态库

上一节静态库的制作需要用若干.o文件,动态库由于在程序中被用到响应的库函数,才会被加载到内存,然后去寻址执行相应函数,因此动态库需要生成"与位置无关的代码"

地址回填

image

程序中要使用动态库中的函数,不能依赖main在做地址偏移,也就是上图中,如果func1和func2动态库的库函数,则无法找到相应的地址,因为执行的ELF文件,没有经过.o->ELF的地址回填步骤,所以动态库需要生成与位置无关的代码-fPIC

静态库与动态库函数反汇编比较——延迟绑定

objdump -dS ELF查看反汇编

动态库加载到内存,@plt被替换掉,动态库函数才会有地址——延迟绑定

image

动态库制作

生成与位置无关的代码—— -fPIC

制作.o时,增加参数,-fPIC

gcc -c add.c add.o -fPIC

image

gcc -share 制作动态库.so

gcc -shared -o libmylib.so add.o sub.o div1.o

image

编译ELF时,指定所用的动态库 -l: 指定库名 -L: 指定库路径

gcc main.c -o main -lmymath -L./lib

image

动态库加载错误及解决办法

根据上一节的步骤,可以利用源码和动态库生成可执行文件,运行时会报下面的错误:

image

链接器:工作于链接阶段,工作时需要-l -L

动态链接器:工作于程序运行阶段,工作时需要提供动态库所在目录位置

二者无关,非说有关系,那就是张三和张三丰的关系~

【加载错误原因/解决办法】

总之,动态库在工作时,动态链接器会去几个固定位置找.so的位置:

  1. 环境变量:export LD_LIBRARY_PATH=./lib,环境变量只能使一个终端进程生效,临时办法

  2. 配置文件:

    在home目录下的.bashrc中添加export LD_LIBRARY_PATH=lib的绝对路径,然后source .bashrc,非临时办法

    image

  3. xx.so放到系统库目录下:/lib,不建议这么做

ldd指令查看动态库依赖】

如果xx.so加载失败,=>后面的动态库路径是空

image

  1. 修改/etc/ld.so.conf配置文件

​ 【1】sudo vi /etc/ld.so.conf,添加你的动态库路径

​ 【2】sudo ldcofig -v ,更新查找动态块的路径

​ 【3】测试是否好了

标签:静态,ELF,so,动态,制作,库函数
From: https://www.cnblogs.com/kongweisi/p/18092627

相关文章

  • 动态代理
    1.创建接口publicinterfaceiTestDemo{voidtest1();voidtest2();}2.创建类接入接口并对方法进行重写publicclassiTestDemoImplimplementsiTestDemo{@Overridepublicvoidtest1(){System.out.println("执行test1方法");}@Overridepublicvoidtest2(){......
  • nginx挂载配置文件和日志-静态目录-方式二
    环境说明linux系统版本:lsb_release-a docker版本:docker-v Nginx镜像版本:1.24.0 不同的操作系统以及软件版本,可能会遇到不一样的问题,一定要注意版本问题。 .1.创建需要挂载的文件目录,比如html和log,还有配置文件nginx.conf.自己首先创建一个目录,结构如下。 ......
  • 蓝桥杯—蓝肽子序列—动态规划
    蓝肽子序列dp[i][j]表示L1,L2前i,j个字段有多少个公共子序列,对于一个Xi和Yj(L1,L2的前i,j个字段形成序列.如果xi=yj(第i,j字段),则dp[i][j]=dp[i-1][j-1]+1(前面的公共字段加一).否则,dp[i][j]=max(dp[i-1][j],dp[i][j-1]),考虑前后情况的最大值。最后输......
  • P1002 [NOIP2002 普及组] 过河卒(动态规划)
    #include<bits/stdc++.h>usingnamespacestd;longlongdp[30][30];boolm[30][30];intmain(){ intAx,Ay,Mx,My; cin>>Ax>>Ay>>Mx>>My; Ax+=2;Ay+=2;Mx+=2;My+=2; dp[2][1]=1; m[Mx][My]=1; m[Mx-2][My-1]......
  • JAVA面向对象高级三:内部类概述,成员内部类,静态内部类
            静态内部类:     局部内部类: ......
  • 【免费】基于扩展(EKF)和无迹卡尔曼滤波(UKF)的电力系统动态状态估计
    目录1 主要内容2 部分代码3 程序结果4下载链接1 主要内容该程序对应文章《PowerSystemDynamicStateEstimationUsing ExtendedandUnscentedKalmanFilters》,电力系统状态的准确估计对于提高电力系统的可靠性、弹性、安全性和稳定性具有重要意义,虽然近......
  • 配置动态刷新@RefreshScope引起的取值为null
    配置动态刷新@RefreshScope引起的取值为null 在SpringCloudConfig动态刷新demo编写中,分为三个步骤: 1)git端配置更改,代码提交 2)手动刷新配置: POST请求:http://localhost:3355/actuator/refresh  3)客户端访问配置:http://localhost:3355/testConfig 控制类代码如下:......
  • vue3 动态编译组件失败:Component provided template option but runtime compilation
    根据vue3官方文档路由,写了如下一个简单的页面来模拟路由的实现。为了减少*.vue文件的个数,在这个但页面中,使用defineComponent通过object定义组件。<scriptsetup>import{ref,computed,defineComponent}from'vue'constHome=defineComponent({template:`......
  • 数码管的动态显示
    1.共阴极数码管实现HELLO #include<reg51.h>charstr[]={0x76,0x79,0x38,0x38,0x3F};//HELLOcharwei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; voiddelay(intn){ inti=0,j=0; for(i=0;i<n;i++) { for(j=0;j<120;j++); }} voidseg(){ ......
  • 100道面试必会算法-09-最大子数组和(初探动态规划)
    100道面试必会算法-09-最大子数组和(初探动态规划)题目一个整数数组nums,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组是数组中的一个连续部分。示例1:输入:nums=[-2,1,-3,4,-1,2,1,-5,4]输出:6解释:连续子数组[4,-1,2,1]的和最大,......