【嵌入式学习笔记-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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网络文件共享服务

一.存储类型 直连式存储&#xff1a;Direct-Attached Storage&#xff0c;简称DAS 存储区域网络&#xff1a;Storage Area Network&#xff0c;简称SAN&#xff08;可以使用空间&#xff0c;管理也是你来管理&#xff09; 网络附加存储&#xff1a;Network-Attached Storage&…

gogs git创建仓库步骤

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

IO网络2.0

思维导图 机械臂 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <myhead.h> #define SER_PORT 8888 #define SER_IP "192.168.122.68" //服务端//TCP客户端 int main(int argc, const char *argv[]) {//创建套接字…

大模型理论基础1

大模型理论基础1 第一章&#xff1a;引言 语言模型 自回归语言模型 概率的链式法则&#xff1a; 在自回归语言模型 p 中生成整个序列 X1:L&#xff0c;我们需要一次生成一个令牌(token)&#xff0c;该令牌基于之前以生成的令牌进行计算获得&#xff1a; 其中T≥0 是一个控…

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

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

2024年百场进校公益安全培训开启

自2023年年底&#xff0c;上海风暴救援队积极策划并推动了2024年的“百场进校传安全”培训项目。经过在东方锦绣于2023年12月14日、上钢新村幼儿园于2023年12月28日的先期测试&#xff0c;项目于2024年1月5日在齐河路幼儿园正式启动。随后&#xff0c;于2024年1月11日在浦南幼儿…

一款基于.NET开发的免费的火车票分流抢票软件

前言 接近年底了又到了全员抢票的日子&#xff0c;今天有同学在技术群里问有没有黄牛推荐帮忙抢车票的。今天分享一个我一直在用的基于.NET开发的、完全免费的火车票分流抢票软件&#xff1a;Bypass。 软件介绍 Bypass是一款基于.NET开发的、完全免费的火车票分流抢票软件&am…

STM32F103标准外设库——认识STM32(一)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的在校大学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;V…

【单片机】STM32 ARM Cortex-M0 微控制器特性概述 双排 TSSOP封装好手工焊接的STM32芯片,双排

STM32F070CB STM32F070RB STM32F070C6 STM32F070F6 在嵌入式系统和物联网应用中&#xff0c;ARM Cortex-M0 微控制器以其强大的性能和丰富的功能而备受瞩目。本文将介绍该微控制器的主要特性&#xff0c;使读者更好地了解其适用范围和潜在应用。 核心特性 ARM 32位 Cortex…

rime中州韵小狼毫 联想词组 滤镜

教程目录&#xff1a;rime中州韵小狼毫须鼠管安装配置教程 保姆级教程 100增强功能配置教程 在 rime中州韵小狼毫 自定义词典 一文中&#xff0c;我们分享了如何在rime中州韵小狼毫须鼠管输入法中定义用户自定义词典&#xff1b;通过自定义词典&#xff0c;我们可以很方便的在…

Github仓库使用方式

主要参考&#xff1a; 「详细教程」使用git将本地项目上传至Github仓库&#xff08;MacOS为例&#xff09;_github上传代码到仓库-CSDN博客 新建文件夹参考&#xff1a; GitHub使用指南——建立仓库、建立文件夹、上传图片详细教程-CSDN博客 一、新建一个 github 仓库&#…

鸿蒙生态,对开发者来说有什么机遇?

在之前的文章中&#xff0c;我们探讨了鸿蒙应用开发中ArkTS的重要性。作为TypeScript的超集&#xff0c;ArkTS不仅继承了TypeScript的优秀特性&#xff0c;还具备自身独特的优势。 随着鸿蒙原生应用的全面开启&#xff0c;开发者们将迎来无数的机遇和挑战。本文将深入剖析鸿蒙…

强化学习应用(二):基于Q-learning的无人机物流路径规划研究(提供Python代码)

一、Q-learning简介 Q-learning是一种强化学习算法&#xff0c;用于解决基于马尔可夫决策过程&#xff08;MDP&#xff09;的问题。它通过学习一个价值函数来指导智能体在环境中做出决策&#xff0c;以最大化累积奖励。 Q-learning算法的核心思想是通过不断更新一个称为Q值的…

自定义SpringBoot项目启动时控制台图标(如来佛祖,永不宕机)

自定义SpringBoot项目启动时控制台图标(如来佛祖&#xff0c;永不宕机) 默认的启动图标&#xff08;spring&#xff09; 自定义下载喜欢的banner.txt文件&#xff0c;将其放到resources目录下&#xff0c;springboot启动时会自动扫描更换启动图标 banner生成网站&#xff1a;…

工智能基础知识总结--神经网络

什么是神经网络 逻辑回归、感知机均只包含一个输入层以及一个输出层,只能处理线性可分问题。如果在输入层与输出层之间加入一层到多层的隐藏层,就会得到神经网络结构。 神经网络一般由输入层、隐藏层、输出层构成,下图展示了其一般结构: 隐藏层之所称之为隐藏层,是因为在…

git切换到另一分支更改也会随之过去

一次的修改如果没有 commit如果切换到另一分支就会把修改带到另一个分支 这时可以使用 git stash 其他使用场景 切换分支&#xff1a;当正在一个分支上工作&#xff0c;但需要临时切换到另一个分支处理一些紧急任务时&#xff0c;可以使用 git stash 保存当前的工作进度。完成…

2024年烟花爆竹储存证考试题库及烟花爆竹储存试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年烟花爆竹储存证考试题库及烟花爆竹储存试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人员上岗证考试大纲随机…

排序算法6---快速排序(非递归)(C)

回顾递归的快速排序&#xff0c;都是先找到key中间值&#xff0c;然后递归左区间&#xff0c;右区间。 那么是否可以实现非递归的快排呢&#xff1f;答案是对的&#xff0c;这里需要借助数据结构的栈。将右区间左区间压栈&#xff08;后进先出&#xff09;&#xff0c;然后取出…

web自动化实现登录的几种方式

目录 前言 一、pythonunittest框架实现登录功能 二、pythonselenium实现登录功能 三、pythonrequests库实现登录功能 前言 今天主要想介绍python语言不同的自动化测试框架的结合方式来模拟登录功能。想了解自动化测试框架的同学不要错过哦&#xff01; 一、pythonunittest框…

软件测试|selenium 元素无法选择异常的原因及解决

简介 在进行 Web 自动化测试时&#xff0c;使用 Selenium 可能会遇到各种异常情况。其中之一就是 ElementNotSelectableException 异常&#xff0c;该异常通常意味着在尝试选择一个不可选元素时出现了问题。本文将详细介绍这个异常的原因、可能的解决方法&#xff0c;并提供示…