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

这篇具有很好参考价值的文章主要介绍了【嵌入式学习笔记-02】什么是库文件,静态库的制作和使用,动态库的制作和使用,动态库的动态加载。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

什么是库文件?

编程模型的发展

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

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

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

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

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

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

什么是库文件?

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

静态库的制作和使用

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

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

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

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

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

    • 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。
  • 链接动态库过程

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

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

    • 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文章来源地址https://www.toymoban.com/news/detail-791889.html

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

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

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

  • 辅助工具

    • 查看符号表: nm

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

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

到了这里,关于【嵌入式学习笔记-02】什么是库文件,静态库的制作和使用,动态库的制作和使用,动态库的动态加载的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 02.sqlite3学习——嵌入式数据库的基本要求和SQLite3的安装

    目录 嵌入式数据库的基本要求和SQLite3的安装 嵌入式数据库的基本要求 常见嵌入式数据库 sqlite3简介 SQLite3编程接口模型 ubuntu 22.04下的SQLite安装 (1)安装SQLite3软件 sudo apt-get install sqlite3 (2)安装库文件 sudo apt-get install libsqlite3-dev 安装成功后输入sqlite3查看 (3)安装sqlite3可

    2024年02月11日
    浏览(73)
  • 【嵌入式学习笔记】嵌入式基础9——STM32启动过程

    程序段交叉引用关系(Section Cross References):描述各文件之间函数调用关系 删除映像未使用的程序段(Removing Unused input sections from the image):描述工程中未用到被删除的冗余程序段(函数/数据) 映像符号表(Image Symbol Table):描述各符号(程序段/数据)在存储器中的地址、类

    2024年02月15日
    浏览(87)
  • 什么是多态?多态有什么用途?(嵌入式学习)

    多态(Polymorphism)是面向对象编程中的一个重要概念,指的是同一种操作或函数可以在不同的对象上具有不同的行为。它允许以一种统一的方式使用不同类型的对象,而不需要关心具体对象的类型。 多态性可以通过两种方式实现:静态多态和动态多态。 静态多态(Static Pol

    2024年02月09日
    浏览(46)
  • 嵌入式学习笔记汇总

    本文整理STM32、STM8和uCOS-III的所有文章链接。 源码:mySTM32-learn STM32学习笔记(1)——LED和蜂鸣器 STM32学习笔记(2)——按键输入实验 STM32学习笔记(3)——时钟系统 STM32学习笔记(4)——NVIC中断优先级管理和外部中断EXTI STM32学习笔记(5)——系统定时器SysTick STM32学习笔

    2023年04月20日
    浏览(73)
  • 嵌入式软件测试笔记12 | 什么是状态转换测试?如何开展?

    嵌入式系统有些表现出基于状态的行为,设计此系统可使用基于状态的建模; 在设计过程中,创建的模型可作为测试设计的基础; 以下将描述基于状态的模型来导出测试用例的技术。 此技术目标是:验证事件、动作、行为与转台转换之间的关系; 通过此技术,可判定系统基

    2024年02月17日
    浏览(60)
  • 嵌入式学习笔记——SPI通信

    之前已经介绍了STM32的ADC、DMA、EXTI、TIME、NVIC、USART以及普通IO模式,此系列笔者还打算写最后三个大的内容,分别是SPI通信、IIC通信以及看门狗,后面就看大家的需求了,需要什么可以留在评论区,本文首先来介绍SPI的有关知识。 在通信协议分类的介绍中,提到过SPI,它是一

    2023年04月09日
    浏览(48)
  • 嵌入式学习笔记——IIC通信

    本文接着之前的M4系列介绍,对另外一个十分常见的通信总线进行一个介绍,就是IIC总线。 首先,还是找个免费劳动力来做一个官方的介绍,下面这一段话非常全面的介绍了IIC的各个特征,用之前提到的通信特征来总结,IIC是一种串行,同步,半双工,板级有线通信。与SPI对

    2024年02月06日
    浏览(77)
  • 嵌入式学习笔记——SysTick(系统滴答)

    上一篇中,介绍了关于STM32F407的时钟系统,在了解了系统的时钟后,最重要的内容就是搞定定时器的操作,本文从最基本的定时器,也是内核里面自带的一个定时器——SysTick(系统滴答)来进行介绍。旨在搞清楚什么是系统滴答,系统滴答有什么用,系统滴答怎么用。 SysTick这

    2024年01月21日
    浏览(46)
  • 【嵌入式】Thumb指令集(学习笔记)

    ARM开发工具完全支持Thumb指令,应用程序可以灵活的将ARM和Thumb子程序混合编程以便在例程的基础上提高性能或代码密度。在编写Thumb指令时,先要用伪指令CODE16声明(ADS的编译环境下),而且在ARM指令中要使用BX指令跳转到Thumb指令,以切换处理器状态。 Thumb指令集编码如下:

    2023年04月22日
    浏览(49)
  • 【嵌入式算法】学习笔记(一):数字滤波算法

    最近在做直流电机的毕设中,由于需要采集转速,电流,电压,温度等参数,常规的采集容易受到干扰,所以特意复习了一下关于数字滤波有关的知识,并作出相应的整理。 本文对数字滤波进行简单介绍,讲解七种常用的滤波算法并用C语言实现,并比较其优缺点 。由于篇幅

    2023年04月22日
    浏览(97)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包