首页 > 其他分享 >静态库与动态库

静态库与动态库

时间:2024-04-09 20:02:03浏览次数:21  
标签:main 动态 符号 静态 int calc dlopen 加载

静态库

静态库的本质时将多个目标文件打包成一个文件,而链接静态库就是将库中被调用的代码复制到调用模块中,拓展名为.a

举例:

calc.h

//计算模块头文件
#ifndef _CALC_H_
#define _CALC_H_

int add(int a,int b);
int sub(int a,int b);


#endif //_CALC_H_

calc.c

#include "calc.h"

int add(int a,int b){
    return a+b;

}

int sub(int a,int b){
    return a-b;
}

编译.c文件:

gcc -c calc.c // 仅编译不链接,为了生成.o

制成静态库

ar -r libtest.a calc.o

按照上述命令就可以制作成libtest.a静态库。接下来如果要使用该库中的方法,可参考如下:
main.c

#include "show.h"
#include "calc.h"

int main(){
    
    int a=145,b=897;
    show(a,'+',b,add(a,b));
    
    
    
    return 0;

}

然后在终端

gcc main.c libtest.a

 如果库和main文件不在同一目录

gcc main.c -ltest -L/yourPath

优缺点

优点

执行速度块

可执行文件不依赖库存在

缺点

 文件体积较大

更新困难,维护成本高

动态库

与静态库相比,链接动态库不需要将被调用的函数代码复制到包含调用代码的可执行文件中,相反链接器会在调用语句处嵌入一段指令,在该程序执行到这段指令时,会加载该动态库并寻找被调用函数的入口地址并执行

如果动态库中的代码同时被多个进程所用,动态库在内存中的实例仅需一份,为所有使用该库的进程共享,也叫共享库。

编译

gcc -c -fpic calc.c show.c(pic:位置无关量,每个函数在文件里面都有一个固定的偏移量,不管它映射到哪一个进程中虽然地址不一样,但是在映射后的地址上加上偏移量就能准确找到函数位置)
gcc -shared calc.o show.o -o libtest.so

链接动态库

gcc main.c -ltest -L/myPath

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:path
gcc main.c -ltest

动态加载

在程序执行的过程中,开发人员可以动态加载共享库(需要用的时候就加载)

动态加载库需要的函数:

dlopen() 函数详解

头文件:#include <dlfcn.h>  链接 -ldl

#include <dlfcn.h>

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

dlopen() 函数是 Linux 和 Unix-like 系统中用于动态加载共享库的核心接口。它接受两个参数:

  • const char *filename:指定了待加载库文件的路径。可以是绝对路径或相对路径。若使用相对路径,其相对于当前工作目录或环境变量 LD_LIBRARY_PATH 中列出的目录。

  • int flag:加载模式标志,用于控制库的加载行为和符号可见性。常见的标志有:

    • RTLD_LAZY:延迟绑定(默认)。仅解析库中符号的引用,直到它们首次被调用时才解析和解决。
    • RTLD_NOW:立即绑定。在 dlopen() 调用时立即解析并解决所有符号引用。
    • RTLD_LOCAL(默认):加载的库中的符号对其他已加载库不可见。
    • RTLD_GLOBAL:加载的库中的符号对其他已加载库可见,允许跨库间的符号引用。

成功加载库后,dlopen() 返回一个非空的句柄(handle),该句柄是后续使用 dlsym() 等函数访问库内资源的关键。如果加载失败,dlopen() 返回 NULL。可通过 dlerror() 函数获取详细的错误信息。

char *dlerror(void);

dlopen() 的搭档:dlsym() 与 dlclose() 

dlsym():查找并获取库中符号
dlsym():查找并获取库中符号

dlsym() 用于从已加载库中查找并获取指定符号(函数或全局变量)的地址。参数:

  • void *handle:由 dlopen() 返回的库句柄。
  • const char *symbol:要查找的符号名称(函数名或变量名)。

成功找到符号时,dlsym() 返回指向该符号的指针。若找不到或发生错误,返回 NULL。同样,使用 dlerror() 获取错误信息

dlclose():卸载已加载库
int dlclose(void *handle);

dlclose() 用于释放由 dlopen() 加载的库资源,使其从进程中卸载。参数:

  • void *handle:待卸载库的句柄。

返回值:

  • 0 表示成功卸载。
  • 非零值表示卸载失败,可通过 dlerror() 获取原因。

标签:main,动态,符号,静态,int,calc,dlopen,加载
From: https://blog.csdn.net/a_Loki/article/details/137538137

相关文章

  • 静态代码分析
    准备条件:linux服务器、可执行docker命令拉取sonarqube的镜像       dockerpullsonarqube安装sonarqube服务       dockerrun-d--namesonarqube\      -eSONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true\      -e......
  • datax 使用 增量同步需要动态传入参数
    datax使用阿里开源,主要用于离线数据同步。官方文档使用简单,主要就是写json配置对应的参数,重哪里读写到哪里去,中间可以转换脱敏等。环境依赖Python装好环境简单使用pythonE:\datax\bin\datax.pyE:\datax\job\mysqltomysql.json增量同步需要动态传入参数也就......
  • 顺序表(动态)
    目录1.顺序表的结构2.顺序表的分类2.1静态顺序表2.2动态顺序表3.接口实现3.1初始化3.2尾插3.3头插3.4尾删3.5头删3.6在指定位置之前插入数据3.7删除指定位置上的数据3.8销毁顺序表1.顺序表的结构顺序表在逻辑结构和物理结构(存储结构)上都是连续的顺序......
  • vue canvas绘制信令图,动态显示标题、宽度、高度
    需求:1、 根据后端返回的数据,动态绘制出信令图2、根据 dataStatus返回值:0和1,判断文字内容的颜色,0:#000,1:red3.、根据lineType 返回值:0和1, 判断箭头线的显示是实线、虚线4、根据返回的文字内容的换行符:“\r\n”自动换行(这步比较难,得计算高度)最后的效果图大......
  • java -动态sql语句
    数据库算法双子针、动态规划、二分查找、贪心算法、深度优先搜索、字符串、递归、字典树、排序、链表等元素作用描述if......
  • C# List 根据传入的分组字段,动态分组
     动态分组:publicstaticclassDynamicLinqExtensions{///<summary>///分组查询///</summary>///<typeparamname="T"></typeparam>///<paramname="source">数据源</param>///<p......
  • ludic 基于纯python 开发动态html 页面的框架
    ludic使用了htmx进行页面的处理,同时基于starlette提供asgiweb能力包含的特性基于python的无缝的htmx集成快速开发web基于python类型系统的类型组件基于starlette的异步搞性能web处理基于pythonf-strings的html构建基于主题的组件css样式添加说明目前ludic......
  • DS-Net:可落地的动态网络,实际加速1.62倍,快改造起来 | CVPR 2021 Oral
    论文提出能够适配硬件加速的动态网络DS-Net,通过提出的double-headed动态门控来实现动态路由。基于论文提出的高性能网络设计和IEB、SGS训练策略,仅用1/2-1/4的计算量就能达到静态SOTA网络性能,实际加速也有1.62倍 来源:晓飞的算法工程笔记公众号论文:DynamicSlimmableNetwo......
  • el-table 表头添加Tooltip render-header动态传参
    给el-table表头添加Tooltip,光标移动到表头问号区域,自动弹出tooltip提示render-header传参方式<el-table-columnprop="usedCredit"label="已占授信额度(元)"width="140"header-align="center"align=&......
  • 对于动态规划的感悟
    1.明确定义的dp数组的含义2.找到递推公式在递推公式中我有以下总结一、斐波那契数列,爬楼梯的递推公式为dp[i]=dp[i-1]+dp[i+2],种类问题二、不同路径问题:规定走的方向,dp[i][j]=dp[i][j-1]+dp[j-1][i](左下)三、整数拆分,dp[i]=j*dp[i-j]初始化dp[2]=1,第一层for循环从i=3开始j......