【Linux】————动静态库

news2024/10/22 20:58:42

 9efbcbc3d25747719da38c01b3fa9b4f.gif

                                                      作者主页:     作者主页

                                                      本篇博客专栏:Linux

                                                      创作时间 :2024年10月22日

9efbcbc3d25747719da38c01b3fa9b4f.gif

一.库的定义

什么是库,在windows平台和linux平台下都大量存在着库。

本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。

由于windows和linux的本质不同,因此二者库的二进制是不兼容的。

本文仅限于介绍linux下的库。

二.库的种类

1. 在windows中

.dll 动态库

.lib 静态库

2. 在linux中

.so 动态库

.a      静态库

二者的不同点在于代码被载入的时刻不同。

静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。

共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小。

三.库存在的意义

库是别人写好的现有的,成熟的,可以复用的代码,你可以使用但要记得遵守许可协议。

现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。共享库的好处是,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。

四.库文件是如何产生的在linux下

静态库的后缀是.a,它的产生分两步:

Step 1.由源文件编译生成一堆.o,每个.o里都包含这个编译单元的符号表

Step 2.ar命令将很多.o转换成.a,成文静态库

动态库的后缀是.so,它由gcc加特定参数编译产生。

五.程序在不同环境下运行时怎么寻找库

1. Linux系统默认到哪里找命令,如果命令不在那里,该怎么设置?

(1) Linux在运行一条命令时,默认会到 /bin , /sbin ,, /usr/bin, /usr/sbin目录下去找;如果找不到则报command not found
(2)如果命令存放在其他路径下,我们可以通过export PATH导出,不过这样只是临时生效;
(3) 如果想让所有用户生效,则修改/etc/profile,里面通过export PATH导出路径;
(4) 在PC上如果只想对本用户生效,则修改~/.bash_profile

2. LInux程序在运行时到哪里找动态库, 如果动态库不在那里,该怎么设置?

(1)若是在开发板程序运行时:修改/etc/profile,export LD_LIBRARY_PATH添加库的其他存放路径。

(2)若是在片PC上程序运行时:动态库默认路径为/usr/lib和/lib,可在/etc/ld.so.conf中添加指定动态库搜索路径,通过LD_LIBRARY_PATH(LD_LIBRARY_PATH是Linux环境变量名,该环境变量主要用于指定查找共享库(动态链接库)时除了默认路径之外的其他路径)命令指定,假如现在需要在已有的环境变量上添加新的路径名,则采用如下方式:

LD_LIBRARY_PATH=NEWDIRS:$LD_LIBRARY_PATH.(newdirs是新的路径串)。

注:在linux下可以用export命令来设置这个值,比如

在linux终端下输入:export LD_LIBRARY_PATH=/opt/au1200_rm/build_tools/bin: $LD_LIBRARY_PATH:

然后再输入:export,即会显示是否设置正确

export方式在重启后失效,所以也可以用 vim /etc/bashrc ,修改其中的LD_LIBRARY_PATH变量。

六.如何知道一个可执行程序依赖哪些库

ldd命令可以查看一个可执行程序依赖的共享库

七:重点

1.静态库:

1.1、怎么做静态库:

在Linux环境下,通常使用GCC(GNU Compiler Collection)编译器来编译源代码,并使用ar(archiver)工具来创建静态库

  1. 编写源代码:首先,你需要有一些源代码文件,比如 x.c ,y.c ,z.c

  2. 编译源代码为对象文件:使用GCC编译器将源代码编译为目标文件(.o文件)。

  3. 创建静态库:使用 ar工具将对象文件打包成静态库。

头文件是一个手册提供函数的声明,告诉用户怎么用;.o提供实现,我们只需要补上一个main函数,调用头文件提供的方法,然后和.o进行链接,就能形成可执行。

头文件是一个手册提供函数的声明,告诉用户怎么用;.o提供实现,我们只需要补上一个main函数,调用头文件提供的方法,然后和.o进行链接,就能形成可执行。

mymath.h

#pragma once // 防止头文件重复包含
 
#include <stdio.h>
 
int Add(int x,int y);

mymath.c

#include "mymath.h"
 
int Add(int x,int y)
{
  return x + y;
}

mystdio.h

#pragma once 
 
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
 
#define LINE_SIZE 1024
#define FLUSH_NOW  1
#define FLUSH_LINE 2
#define FLUSH_FULL 4
 
typedef struct _myFILE  
{
  unsigned int flags;
  int fileno;
  // 缓冲区
  char cache[LINE_SIZE];
  int cap;// 容量
  int pos;// 下次写入的位置
}myFILE;
 
myFILE* my_fopen(const char* path,const char* flag);
void my_fflush(myFILE* fp);
ssize_t my_fwrite(myFILE* fp,const char* data,int len);
void my_fclose(myFILE* fp);

mystdio.c

#include "mystdio.h"
 
myFILE* my_fopen(const char* path,const char* flag)
{
  int flag1 = 0;
  int iscreate = 0;
  mode_t mode = 0666;
  if(strcmp(flag,"r") == 0)
  {
    flag1 = O_RDONLY;
  }
  else if(strcmp(flag,"w") == 0)
  {
    flag1 = (O_WRONLY | O_CREAT | O_TRUNC);
    iscreate = 1;
  }
  else if(strcmp(flag,"a") == 0)
  {
    flag1 = (O_WRONLY | O_CREAT | O_APPEND);
    iscreate = 1;
  }
  else 
  {}
 
  int fd = 0;
  if(iscreate)
    fd = open(path,flag1,mode);
  else 
    fd = open(path,flag1);
  
  if(fd < 0) return NULL;
  
  myFILE* fp = (myFILE*)malloc(sizeof(myFILE));
  if(fp == NULL) return NULL;
 
  fp->fileno = fd;
  fp->flags = FLUSH_LINE;
 
  fp->cap = LINE_SIZE;
  fp->pos = 0;
 
  return fp;
}
void my_fflush(myFILE* fp)
{
  write(fp->fileno,fp->cache,fp->pos);
  fp->pos = 0;
}
ssize_t my_fwrite(myFILE* fp,const char* data,int len)
{
  // 写入的本质是拷贝,条件允许就刷新
  memcpy(fp->cache + fp->pos ,data,len);// 考虑扩容与越界问题
  fp->pos += len;
  
  if((fp->flags&FLUSH_LINE) && fp->cache[fp->pos-1] == '\n')
  {
      my_fflush(fp);
  }
  return len; 
}
void my_fclose(myFILE* fp)
{
  my_fflush(fp);
  close(fp->fileno);
  free(fp);
}

main.c

#include "mymath.h"
#include "mystdio.h"
#include <string.h>
#include <stdio.h>
 
int main()
{
  int a = 10;
  int b = 20;
  
  printf("%d + %d  = %d\n",a,b,myAdd(a,b));
 
  myFILE* fp = my_fopen("log.txt","w");
  if(fp == NULL) return 1;
 
  const char* message = "这是我写的...\n";
 
  my_fwrite(fp,message,strlen(message));
  my_fclose(fp);
  return 0;
}

编译并执行程序

将.c文件(源文件)编译成.o文件(目标文件) [ -c选项告诉GCC只编译和汇编,但不链接]

使用.h 文件和.o 文件编译main.c程序

 gcc main.c 只编译了main.c文件,并没有包含对mymath.o 和 mystdio.h 的链接操作,因为main.c 依赖于mymath.h 和 mystdio.h 中声明的函数,因此仅编译main.c是不够的。

解决办法一:

将.o文件 和.c文件一起编译链接。

解决办法二:

将main.o也编译成.o文件

解决方法三:通过ar指令将所有.o文件打包:

ar -rc libmyc.a *.o # 将所有.o文件打包成libmyc.a文件

1.2、怎么使用静态库

  • 方式一:直接使用打包的文件

为了更好的使用静态库,我们把前面打包的文件拷贝到另外的目录进行操作。

这里我们创建一个other目录并cd进去

然后将之前形成的libmystdio.a文件以及两个.h头文件拷贝过来拷贝过来

这样就可以了

  •  方式二:将打包的文件拷贝到系统库中(严重不推荐)

通过这几步操作就将这些文件拷贝到啦目录底下

但是直接使用gcc编译还是会报错,因为该方法的实现是我们自己写的,gcc/g++不认识,所以直接编译会报错。 

在gcc编译.c文件之后需要加参数,-l libmyc.a,且需要去掉lib和.a,因此正确的命令是gcc main.c -lmyc (-l后面可以加空格也可以不加空格) 

 第二种方式不推荐,因此演示完之后最好将拷贝的文件给删除掉。

方式三:通过命令链接静态库

为什么不能直接使用 gcc main.c myc.a 因为告诉了gcc/g++编译器,但是没有告诉操作系统!!!

使用静态库:在编译其他程序时,可以通过-I(指定用户自定义头文件搜索路径)  -L(指定用户自定义库文件搜索路径)和 -l(执行确定的第三方库名称,去掉前缀lib和后缀.a)选项来链接静态库

最后:

十分感谢你可以耐着性子把它读完和我可以坚持写到这里,送几句话,对你,也对我:

1.一个冷知识:
屏蔽力是一个人最顶级的能力,任何消耗你的人和事,多看一眼都是你的不对。

2.你不用变得很外向,内向挺好的,但需要你发言的时候,一定要勇敢。
正所谓:君子可内敛不可懦弱,面不公可起而论之。

3.成年人的世界,只筛选,不教育。

4.自律不是6点起床,7点准时学习,而是不管别人怎么说怎么看,你也会坚持去做,绝不打乱自己的节奏,是一种自我的恒心。

5.你开始炫耀自己,往往都是灾难的开始,就像老子在《道德经》里写到:光而不耀,静水流深。

最后如果觉得我写的还不错,请不要忘记点赞✌,收藏✌,加关注✌哦(。・ω・。)

愿我们一起加油,奔向更美好的未来,愿我们从懵懵懂懂的一枚菜鸟逐渐成为大佬。加油,为自己点赞!

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

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

相关文章

虚拟机网络设置为桥接模式

1、打开VMware Workstation Pro&#xff0c;点击“虚拟机—设置”&#xff0c;进入虚拟机设置页面 2、点击“网络适配器”&#xff0c;网络连接选择桥接模式 3、点击“编辑—虚拟网络编辑器”&#xff0c;进入虚拟网络编辑器页面 4、选择桥接模式&#xff0c;并选择要桥接到的…

Flux.using 使用说明书

using public static <T,D> Flux<T> using(Callable<? extends D> resourceSupplier,Function<? super D,? extends Publisher<? extends T>> sourceSupplier,Consumer<? super D> resourceCleanup)Uses a resource, generated by a…

创建人物状态栏

接下来&#xff0c;我们来尝试制作一下我们的UI&#xff0c;我们会学习unity基本的UI系统 ************************************************************************************************************** 我们要先安装一个好用的插件到我们的unity当中&#xff0c;帮助…

Mac电脑:资源库Library里找不到WebServer问题的解决

今天看到一本书里写到Windows电脑自带IIS Web服务器&#xff0c;好奇了一下下&#xff0c;mac电脑自带的又是什么服务器呢&#xff1f;经查询&#xff0c;原来是Apache服务器&#xff0c;这个名字我很熟悉。只是如何设置呢&#xff1f;我从来没用过&#xff0c;于是试验了一番。…

[Linux进程概念]命令行参数|环境变量

目录 一、命令行参数 1.什么是命令行参数 2.为什么要有命令行参数 &#xff08;1&#xff09;书写的代码段 &#xff08;2&#xff09;实际的代码段 3.Linux中的命令行参数 二、环境变量 1.什么是环境变量&#xff1f; 2.获取环境变量 &#xff08;1&#xff09;指令…

OceanBase 的写盘与传统数据库有什么不同?

背景 在数据库开发过程中&#xff0c;“写盘”是一项核心操作&#xff0c;即将内存中暂存的数据安全地转储到磁盘上。在诸如MySQL这样的传统数据库管理系统中&#xff0c;写盘主要有以下几步&#xff1a;首先将数据写入缓存池&#xff1b;其次&#xff0c;为了确保数据的完整性…

【Qt】控件——Qt输入类控件、常见的输入类控件、输入类控件的使用、Line Edit、Text Edit、Combo Box、Spin Box

文章目录 Qt5. Qt显示类控件Line EditText EditCombo BoxSpin BoxQDateTimeEditDialSlider Qt 5. Qt显示类控件 Line Edit QLineEdit 用于表示单行输入框。可以输入一段文本&#xff0c;但是不能换行。 属性说明text输入框中的文本inputMask输入内容格式约束maxLength最大长度…

【HAD】Half-Truth: A Partially Fake Audio Detection Dataset

文章目录 Half-Truth: A Partially Fake Audio Detection Dataset背景key points研究数据集设计评价指标实验基线:utterance-level分类(话语级)基线:segment-level分类(片段级)Half-Truth: A Partially Fake Audio Detection Dataset 会议/期刊:Interspeech 2021 CCF-C…

哈佛医学生一个月吃720个鸡蛋,结果发现......

你们听说过吃鸡蛋还能降低胆固醇的操作吗&#xff1f; 前段时间&#xff0c;哈佛医学院的学生尼克诺尔维茨&#xff08;Nick Norwitz&#xff09;就做了这样一个实验&#xff0c;得出的结果让大家震惊&#xff01; 许多人认为狂吃鸡蛋不会有好处&#xff0c;因为这会摄入大量胆…

FFT过程中自动补零,补零部分FFT结果不为零

在 FFT&#xff08;快速傅里叶变换&#xff09; 中&#xff0c;补零&#xff08;Zero Padding&#xff09;是为了使信号的点数符合 2 的幂次方&#xff0c;以提高 FFT 的计算效率。然而&#xff0c;即使你对信号进行了补零&#xff0c;FFT 计算后在补零部分可能会得到复数结果不…

<项目代码>YOLOv8工具识别<目标检测>

YOLOv8是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题&#xff0c;能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法&#xff08;如Faster R-CNN&#xff09;&#xff0c;YOLOv8具有更高的…

数字化营销助企业在生态平台实现内卷突围

在当今数字化时代&#xff0c;企业竞争激烈&#xff0c;内卷化严重。而数字化生态平台建设与数字化营销为企业带来了新机遇。 数字化生态平台意义重大。它能整合企业内外资源&#xff0c;提高运营效率。打破地域限制&#xff0c;拓展市场&#xff0c;吸引更多客户。还能为企业创…

TCP——Socket

应用进程只借助Socket API发和收但是不关心他是怎么进行传和收的 数据结构 图示Socket连接 捆绑属于隐式捆绑

如何快速解决谷歌网站页面收录难题?

在外贸网站的运营中&#xff0c;页面无法被谷歌收录是一个常见的困扰。即便你的内容再优秀&#xff0c;如果搜索引擎的爬虫无法抓取到你的页面&#xff0c;那一切努力都将白费。而GPC爬虫池服务可以帮助你快速解决网站页面的收录问题。它通过千万级的爬虫池资源&#xff0c;强力…

【信创】银河麒麟安装程序记录

银河麒麟安装程序记录 Step1 添加外网yum源Step2 安装软件安装MySQL&#xff08;8.0.32&#xff09;安装JDK安装jdk17安装Nginx&#xff08;1.21.5&#xff09;安装Redis&#xff08;4.0.14&#xff09;安装Emqx&#xff08;4.4.19&#xff09;安装RocketMQ&#xff08;5.1.4&a…

基于STM32的多功能MP3播放器

基于STM32的多功能MP3播放器 基于STM32的多功能MP3播放器一、项目背景与意义二、系统设计与实现2.1 硬件设计2.2 软件设计2.3 系统调试 三、功能实现与展望四、结论五、附录 基于STM32的多功能MP3播放器 在数字化时代&#xff0c;多功能播放器已成为我们生活中不可或缺的一部分…

Maven骨灰级教程:从小白到高手的终极指南(一)

目录 1. Maven的概念 1.1 什么是Maven 1.2 什么是依赖管理 1.3 什么是项目构建 1.4 Maven的应用场景 1.5 为什么使用Maven 1.6 Maven模型 2.初识Maven 2.1 Maven安装 2.1.1 安装准备 2.1.2 Maven安装目录分析 2.1.3 Maven的环境变量 2.2 Maven的第一个项目 2.2.1…

学习threejs,THREE.ConvexGeometry凸包高级几何体

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.ConvexGeometry凸包高…

Http模块总体设计

在前面的文章中&#xff0c;我们已经实现了一个主从Reactor模型的服务器类&#xff0c;但是由于他只是一个服务器&#xff0c;不涉及任何业务以及协议的处理&#xff0c;那么为了方便用户使用&#xff0c;我们可以预先设置好协议的支持&#xff0c;只需要让用户进行业务处理就行…

【Qt】Windows下Qt连接DM数据库

环境信息&#xff1a;W11 Qt5.12及以上 dm8 QODBC达梦 Windows环境创建ODBC数据源 使用 ODBC 方法访问 DM 数据库服务器之前&#xff0c;必须先配置 ODBC 数据源 在控制面板Windows工具中显示ODBC数据源管理器 ODBC数据源管理器标签 用户 DSN&#xff1a;添加、删除或配置本…