【嵌入式学习笔记-02】什么是库文件,静态库的制作和使用,动态库的制作和使用,动态库的动态加载

【嵌入式学习笔记-02】什么是库文件,静态库的制作和使用,动态库的制作和使用,动态库的动态加载

文章目录

  • 什么是库文件?
    • 编程模型的发展
    • 什么是库文件?
  • 静态库的制作和使用
  • 动态库的制作和使用
  • 动态库的动态加载

什么是库文件?

编程模型的发展

  • 单一模型:
    • 将程序中所有功能全部实现于一个单一的源文件内部。编译时间长,不易于维护和升级不易于协作开发。

image-20240103204445924

  • 分离模型
    • 将程序中的不同功能模块划分到不同的源文件中。缩短编译时间,易于维护和升级,易于协作开发。

image-20240103204611398

  • 对多个目标文件的管理比较麻烦
    • 将多个目标文件统一整理合成为一个文件便于使用和管理,于是就有了库文件。

image-20240103204735103

什么是库文件?

  • 为何要把一个程序分成多个源文件,并由每个源文件编译生成独立的目标文件?
    • 化整为零、易于维护、便于协作。
  • 为何要把多个目标文件合并成一个库文件?
    • 集零为整、方便使用、易于复用。
  • 可以简单的把库文件看成一种代码仓库,它提供给使用者一些可以直接拿来用的变量、函数或类。
    • 库文件一般指计算机上的一类文件,分两种,一种是静态库,另一种是动态库。

静态库的制作和使用

  • 静态库的本质就是将多个目标文件打包成一个文件

  • 链接静态库的过程就是将库中被调用的代码复制到调用模块中

  • 静态库的拓展名是 .a 例: libxxx.a

    image-20240107221233826

  • 以构建数学库为例,静态库的构建顺序如下:

    • 1、编辑库的实现代码和接口声明:

      计算模块:calc.h、calc.c

      显示模块:show.h、show.c

      接口文件:math.h

    • 2、编译成目标文件

      gcc -c calc.c

      gcc -c show.c

    • 3、打包成静态库

      ar -r libmath.a calc.o show.o

  • ar 命令

    • ar[选项] <静态库文件> <目标文件列表>
      -r 将目标插入到静态库中,已存在则更新
      -q 将目标文件追加到静态库尾
      -d 从静态库中删除目标文件
      -t 列表显示静态库中的目标文件
      -x 将静态库展开为目标文件
  • 编辑库的使用代码

    • main.c
  • 编译并链接静态库

    • 直接链接静态库

      gcc main.c libmath.a

    • 用-l指定库名,用-L指定库路径

      gcc mian.c -lmath -L.

  • 用-l指定库名,用LIBRARY PATH环境变量指定库路径

    • export LIBRARY PATH=$LIBRARY_PATH:

    • gcc main.c -lmath

动态库的制作和使用

  • 动态库和静态库不同,链接动态库不需要将被调用的函数代码复制到包含调用代码的可执行文件中,相反链接器会在调用语句处嵌入一段指令,在该程序执行到这段指令时,会加载该动态库并寻找被调用函数的入口地址并执行之。
  • 如果动态库中的代码同时为多个进程所用,动态库在内存的实例仅需一份,为所有使用该库的进程所共享,因此动态库亦称共享库。
  • 动态库的拓展名是 .so 例如libxxx.so。
  • 链接动态库过程

image-20240110213858364

  • 以构建数学库为例,动态库的构建顺序如下:

    • 1、编辑库的实现代码和接口声明:
      计算模块: calc.h、calc.c
      显示模块: show.h、show.c
      接口文件: math.h
    • 2、编译成目标文件
      gcc -c -fpic calc.c
      gcc -c -fpic show.c
    • 3、打包成动态库
      gcc -shared calc.o show.o -o libmath.so
  • 编译链接也可以合并成一步完成。

    • gcc -shared -fpic calc.c show.c -o libmath.so
  • PIC(Position Independent Code,位置无关代码)。

    • 调用代码通过相对地址标识调用代码的位置,模块中的指令与该模块被加载到内存中的位置无关
  • -fPIC:大模式,生成代码比较大,运行速度比较慢,所有平台都支持

  • -fpic:小模式,生成代码比较小,运行速度比较快,仅部分平台支持

  • 编辑库的使用代码

    • main.c
  • 编译并链接动态库

    • 直接链接动态库

      `gcc main.c libmath.so

    • 用-l指定库名,用-L指定库路径

      gcc mian.c -lmath -L.

  • 用-l指定库名,用LIBRARY PATH环境变量指定库路径

    • export LIBRARY PATH=$LIBRARY_PATH:
    • gcc main.c -lmath
  • 运行时需要保证LD LIBRARY PATH环境变量中包含共享库所在的路径用以告知链接器在运行时链接动态。

    • export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
  • 在可执行程序的链接阶段,并不将所调用函数的二进制代码复制到可执行程序中,而只是将该函数在共享库中的地址嵌入到调用模块中,因此运行时需要依赖共享库。

动态库的动态加载

  • 在程序执行的过程中,开发人员可以动态加载共享库 (什么时候用什么时候加载),这样可以提高内存的利用效率。

  • 在程序中动态加载共享库需要调用一组特殊的函数,它们被声明于一个专门的头文件中,并在一个独立的库中予以实现。

  • 使用这组函数需要包含此头文件,并链接该库

    • #include<dlfcn.h>
    • -ldl
  • void* dlopen(char const* filename, int flag)

    • 功能:将共享库载入内存并获得其访问句柄

    • 参数:

      filename 动态库路径,若只给文件名不带目录,则根据LD LIBRARY PATH环境变量的值搜索动态库

      flag 加载方式,可取以下值
      RTLD LAZY - 延迟加载,使用动态库中的符号时才真的加载进内存。

      ​ RTLD NOW - 立即加载。

    • 返回值: 成功返回动态库的访问句柄,失败返回NULL。

    • 句柄: 句柄唯一地标识了系统内核所维护的共享库对象,将作为后续函数调用的参数

  • void* dlsym(void* handle, char const* symbol);

    • 功能:从已被加载的动态库中获取特定名称的符号地址

    • 参数: handle 动态库访问句柄

      ​ symbol 符号名

    • 返回值: 成功返回给定符号的地址,失败返回NULL。

    • 该函数所返回的指针为void*类型,需要造型为与实际目标类型相一致的指针,才能使用。

  • int dlclose(void* handle)

    • 功能:从内存中卸载动态库
    • 参数: handle 动态库句柄
    • 返回值: 返回值: 成功返回0,失败返回非0.
    • 所卸载的共享库未必会真的从内存中立即消失,因为其他程序可能还需要使用该库
    • 只有所有使用该库的程序都显示或隐式地卸载了该库,该库所占用的内存空间才会真正得到释放
    • 无论所卸载的共享库是否真正被释放,传递给dlclose函数的句柄都会在该函数成功返回后立即失效
  • char* dlerror(void)

    • 功能:获取在加载、使用和卸载共享库过程中所发生的错误
    • 返回值: 有错误则返回指向错误信息字符串的指针,否则返回NULL。
  • 辅助工具

    • 查看符号表: nm

      • 列出目标文件、可执行程序、静态库、或共享库中的符号
      • 例: nm libmath.a
    • 查看依赖: ldd

      • 查看可执行文件或者共享库所依赖的共享库
      • 例: ldd a.out

加载、使用和卸载共享库过程中所发生的错误

  • 返回值: 有错误则返回指向错误信息字符串的指针,否则返回NULL。

  • 辅助工具

    • 查看符号表: nm

      • 列出目标文件、可执行程序、静态库、或共享库中的符号
      • 例: nm libmath.a
    • 查看依赖: ldd

      • 查看可执行文件或者共享库所依赖的共享库
      • 例: ldd a.out

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

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

相关文章

Docker-01-安装基础命令

Docker-01-安装&基础命令 文章目录 Docker-01-安装&基础命令一、Docker是什么&#xff1f;二、安装Docker①&#xff1a;卸载旧版②&#xff1a;配置Docker的yum库③&#xff1a;安装Docker④&#xff1a;启动和校验⑤&#xff1a;配置镜像加速01&#xff1a;注册阿里云…

SpringBoot知识02

1、快速生成mapper和service &#xff08;1&#xff09;&#xff08;自动生成简单的单表sql&#xff09; &#xff08;2&#xff09;快速生成多表&#xff08;自动生成常量&#xff09; 2、springboot配置swagger&#xff08;路径不用加/api&#xff09; &#xff08;1&#…

Mindspore 公开课 - GPT

GPT Task 在模型 finetune 中&#xff0c;需要根据不同的下游任务来处理输入&#xff0c;主要的下游任务可分为以下四类&#xff1a; 分类&#xff08;Classification&#xff09;&#xff1a;给定一个输入文本&#xff0c;将其分为若干类别中的一类&#xff0c;如情感分类、…

报名活动怎么做_小程序创建线上报名活动最详细攻略

报名活动怎么做&#xff1a;一篇让你掌握活动策划与营销的秘籍 在当今社会&#xff0c;无论是线上还是线下&#xff0c;活动已经成为企业营销和品牌推广的重要手段。但是&#xff0c;如何策划一场成功的活动呢&#xff1f;这篇文章将为你揭示活动策划与营销的秘籍&#xff0c;…

政采网调试要求及常见问题解决方法

登录平台软件环境要求&#xff1a; 操作系统&#xff1a;建议Win10及以上&#xff08;Win10-64位专业版 版本号17134纯净安装版本&#xff09; 浏 览 器&#xff1a;IE11浏览器、谷歌120.0.6099.217&#xff08;64位正式版&#xff09;浏览器 必要软件&#xff1a;CA互联互通…

Mindspore 公开课 - BERT

BERT BERT模型本质上是结合了 ELMo 模型与 GPT 模型的优势。 相比于ELMo&#xff0c;BERT仅需改动最后的输出层&#xff0c;而非模型架构&#xff0c;便可以在下游任务中达到很好的效果&#xff1b;相比于GPT&#xff0c;BERT在处理词元表示时考虑到了双向上下文的信息&#…

微服务架构设计核心理论:掌握微服务设计精髓

文章目录 一、微服务与服务治理1、概述2、Two Pizza原则和微服务团队3、主链路规划4、服务治理和微服务生命周期5、微服务架构的网络层搭建6、微服务架构的部署结构7、面试题 二、配置中心1、为什么要配置中心2、配置中心高可用思考 三、服务监控1、业务埋点的技术选型2、用户行…

2023年总结:雄关漫道真如铁,而今迈步从头越,今朝得失

2023年悄然离去&#xff0c;感谢大家的帮助、鼓励和陪伴&#xff0c;感谢家人的理解和支持&#xff0c;祝大家新年快乐&#xff0c;阖家幸福&#xff0c;身体健康。像往常一样&#xff0c;今年也会写一篇年终总结&#xff0c;也是自己的第11篇年终总结&#xff0c;题目就叫《雄…

32 二叉树的定义

之前的通用树结构 采用双亲孩子表示法模型 孩子兄弟表示法模型 引出二叉树 二叉树的定义&#xff1a; 满二叉树和完全二叉树 对此图要有印象 满二叉树一定是完全二叉树&#xff0c;但是完全二叉树不一定是满二叉树 小结

Javaweb之SpringBootWeb案例员工管理分页查询的详细解析

3. 员工管理 完成了部门管理的功能开发之后&#xff0c;我们进入到下一环节员工管理功能的开发。 基于以上原型&#xff0c;我们可以把员工管理功能分为&#xff1a; 分页查询&#xff08;今天完成&#xff09; 带条件的分页查询&#xff08;今天完成&#xff09; 删除员工&…

HNU-算法设计与分析-实验4

算法设计与分析实验4 计科210X 甘晴void 202108010XXX 目录 文章目录 算法设计与分析<br>实验41 回溯算法求解0-1背包问题问题重述想法代码验证算法分析 2 回溯算法实现题5-4运动员最佳配对问题问题重述想法代码验证算法分析 3 分支限界法求解0-1背包问题问题重述想法…

gogs git创建仓库步骤

目录 引言创建仓库clone 仓库推送代码 引言 Gogs 是一款类似GitHub的开源文件/代码管理系统&#xff08;基于Git&#xff09;&#xff0c;Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自助 Git 服务。 创建仓库 git中的组织可以把它看成是相关仓库的集合&#xff0c…

DNS主从服务器配置

主从服务器配置&#xff1a; &#xff08;1&#xff09;完全区域传送&#xff1a;复制整个区域文件 #主DNS服务器的配置【主dns服务器的ip地址为192.168.168.129】 #编辑DNS系统配置信息&#xff08;我这里写的增加的信息&#xff0c;源文件里面有很多内容&#xff09; [root…

python中小数据池和编码

嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 ⼀. 小数据池 在说小数据池之前. 我们先看⼀个概念. 什么是代码块: 根据提示我们从官⽅⽂档找到了这样的说法&#xff1a; A Python program is constructed from code blocks. A block is a piece of Python program text…

大电流直流恒温控制电路

一个电子制冷器控制芯片 实物照片 驱动芯片 使用环境12V直流&#xff0c;电流10A 特此记录 anlog 2024年1月15日

2.1.2 一个关于y=ax+b的故事

跳转到根目录&#xff1a;知行合一&#xff1a;投资篇 已完成&#xff1a; 1、投资&技术   1.1.1 投资-编程基础-numpy   1.1.2 投资-编程基础-pandas   1.2 金融数据处理   1.3 金融数据可视化 2、投资方法论   2.1.1 预期年化收益率   2.1.2 一个关于yaxb的…

【C初阶——内存函数】鹏哥C语言系列文章,基本语法知识全面讲解

本文由睡觉待开机原创&#xff0c;转载请注明出处。 本内容在csdn网站首发 欢迎各位点赞—评论—收藏 如果存在不足之处请评论留言&#xff0c;共同进步&#xff01; 这里写目录标题 1.memcpy使用和模拟实现2.memmove的使用和模拟实现3.memset函数的使用4.memcpy函数的使用 1.m…

linux安装MySQL5.7(安装、开机自启、定时备份)

一、安装步骤 我喜欢安装在/usr/local/mysql目录下 #切换目录 cd /usr/local/ #下载文件 wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.38-linux-glibc2.12-x86_64.tar.gz #解压文件 tar -zxvf mysql-5.7.38-linux-glibc2.12-x86_64.tar.gz -C /usr/local …

ERP和MES对接的几种接口方式

在数字化工厂的规划建设中&#xff0c;信息化系统的集成&#xff0c;既是重点&#xff0c;但同时也是难点。ERP和MES对接时&#xff0c;ERP主要负责下达生产计划&#xff0c;MES是执行生产计划&#xff0c;二套系统在数据交互时&#xff0c;需要确保基础数据的一致性&#xff0…

SpringBoot源码分析

一&#xff1a;简介 由Pivotal团队提供的全新框架其设计目的是用来简化新Spring应用的初始搭建以及开发过程使用了特定的方式来进行配置快速应用开发领域 二&#xff1a;运行原理以及特点 运行原理&#xff1a; SpringBoot为我们做的自动配置&#xff0c;确实方便快捷&#…