【Linux】从零开始认识动静态库 - 静态库

news2024/11/20 1:43:16

在这里插入图片描述

送给大家一句话:
永不言弃,就是我的魔法! ——阿斯塔《黑色四叶草》

ଘ(੭ˊ꒳​ˋ)੭✧ଘ(੭ˊ꒳​ˋ)੭✧ଘ(੭ˊ꒳​ˋ)੭✧
ଘ(੭ˊ꒳​ˋ)੭✧ଘ(੭ˊ꒳​ˋ)੭✧ଘ(੭ˊ꒳​ˋ)੭✧
ଘ(੭ˊ꒳​ˋ)੭✧ଘ(੭ˊ꒳​ˋ)੭✧ଘ(੭ˊ꒳​ˋ)੭✧


从零开始认识动静态库

  • 1 前言
  • 2 动静态库概述
  • 3 建立静态库
    • 3.1 背景知识
    • 3.2 建立静态库
    • 3.3 使用静态库
  • Thanks♪(・ω・)ノ谢谢阅读!!!
  • 下一篇文章见!!!

1 前言

今天我们来学习动静态库。我们之前有没有使用过库呢???
当然了:
strerror strstr strcpy memset...等函数都要有具体的实现,那这个具体的实现在哪里呢???就是在我们的库中!

2 动静态库概述

学习了这么多的知识,我们有没有使用过库呢?当然了,我们每次编写文件都会加入头文件,来保证我们可以顺利使用:strerror strstr map list vector 等函数与容器。而想要使用这些接口,一定一定又有对应的实现,那么这个实现是我们自己写的吗?当然不是,而是写在库文件中的。

我们编写一个简单的程序:

 1 #include<stdio.h>
  2 #include<string.h>
  3 #include<stdlib.h>                                                                                                                                                            
  4 
  5 int main()
  6 {
  7   printf("I love you!!!\n");
  8   const char* str = "I am a joker!!!\n";
  9 
 10   char* copy = (char*)malloc(sizeof(char) * 128);
 11   strcpy(copy , str);
 12   printf("%s\n",copy);
 13   free(copy);
 14 
 15   return 0;
 16 }

我们编译一下,然后使用:ldd 文件名来查看所使用的库:
在这里插入图片描述
这就是使用的库文件!

  • 静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库
  • 动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。

直白一点来讲,假如你想玩游戏,静态库就是买一台电脑放在宿舍,动态库就是去网吧与其他人共享。
Linux系统下基本都是使用动态库:
在这里插入图片描述
接下来我们来详细说说静态库和动态库。

实际工作中,80%的情况都是使用动态库!!!

3 建立静态库

我们来谈谈如何建立静态库。

3.1 背景知识

首先我们创建几个头文件和对应的函数实现:
在这里插入图片描述
我们现在有两套方法。
之前我们学过gcc编译成功的文件会变成.o二进制文件(可重定位目标文件),.o文件再经过链接就形成可执行程序。
OK,接下来我们假设一个场景:

今天,老师布置了一项大作业:要求完成一系列方法。你非常顺利的写出来了对应的.h.c文件。这时候你的舍友来问你
舍友:“哥,那个大作业写了没有?”
你回答:“当然了”
舍友随即就客套道:“那啥哥,等哪天请你吃饭,你看看这个…”。
你瞬间就懂了舍友是想要“借鉴”一下大作业:“不行不行,我给你的话,咱俩的代码风格细节就一样了,出事了怎么办…”
你迟钝了一下
你:“也不是没办法,给你打包成.o文件用吧”。

在这个情景下,你不会把源代码给舍友,而是选择给他发一份二进制文件与头文件手册。
在这里插入图片描述
舍友看见了可发愁了,这怎么用啊,舍友连.o文件是什么都不知道。你说:“不用慌,这个和.c文件没有区别,正常调用.h的函数方法就可以”。舍友于是就试了试:

  1 #include"mystdio.h"
  2 #include"mymath.h"
  3 #include <stdio.h>
  4 #include<string.h>
  5 
  6 
  7 int main()
  8 {
  9   int a = 5 ;
 10   int b = 25;
 11 
 12   printf("%d + %d = %d\n",a,b,Sum(a,b));
 13                                               
 14   myFILE* fp = my_fopen("./myfile.txt" , "w");
 15   if(fp == NULL) return 1;
 16 
 17   const char *message = "这就是我的作业\n";
 18 
 19   my_fwrite(fp,message,strlen(message));
 20 
 21   my_fclose(fp);
 22                                                                                                                                                                               
 23   return 0;                                                                                                  
 24 }

舍友看着编写代码时候也没有报错,心里乐开了花,于是迫不及待的进行编译,这一编译可就出事了:
在这里插入图片描述
舍友蒙了,为什么提示找不到对应函数,不是提供了对应的文件了吗?这时你来解围:因为编译链接的时候需要把.o文件也一起进行:
在这里插入图片描述
这下就可以了!!!运行也正常!!!
成功了!!

总结:

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

3.2 建立静态库

接着上面的情景:

后来 ,老师见你们能力挺强,于是给你和舍友布置了新作业,这个新作业需要数十个头文件。你一看终于到了大展身手的时候,可你的舍友愁坏了!!!像上次那样,你把所有的.h.o都发给了舍友,舍友一不小心就漏掉了一两个,这可麻烦了。于是打包发给舍友,但是你的舍友不会解包。突然,你想到个新办法!建立一个静态库发给舍友!!!

这个静态库如何使用呢?
通过命令 ar -rc libmyc.a *.o 就可以创建一个静态库
在这里插入图片描述
于是你就发给了舍友:
在这里插入图片描述
然后继续编译链接就可以了:
在这里插入图片描述
这样就好了!!!这样使用一个静态库就集合了大量的.o文件方法!!!

总结:

  1. 所谓的库文件本质就是把.o文件打包
  2. 静态库提高了开发效率,避免重复的造轮子!

来看一下具体命令:

  • 生成静态库[root@localhost linux]# ar -rc libmymath.a add.o sub.o
    ar是gnu归档工具,rc表示(replace and create)
  • 查看静态库中的目录列表[root@localhost linux]# ar -tv libmymath.a
    rw-r–r-- 0/0 1240 Sep 15 16:53 2017 add.o
    rw-r–r-- 0/0 1240 Sep 15 16:53 2017 sub.o

3.3 使用静态库

那打包好了静态库,应该如何使用静态库呢?

我们搭建一个这样的结构:
在这里插入图片描述
这时候,如果其他人也想使用,我们就通过打包这个mylib发给他们。
想要通过这个使用,就要把这个库安装到系统里!就是把.h头文件安装到操作系统搜索头文件的路径下,.a文件也是这样
在这里插入图片描述
也就是这样,现在我们来试试:
因为现在已经在系统默认路径下了,所以既可以使用< >而不是" "

  1 #include<mystdio.h>
  2 #include<mymath.h>                                                                                                                                                            
  3 #include <stdio.h>                   
  4 #include<string.h>                   
  5                                      
  6                                      
  7 int main()                           
  8 {                                    
  9   int a = 5 ;                        
 10   int b = 25;                        
 11                                      
 12   printf("%d + %d = %d\n",a,b,Sum(a,b));
 13                                      
 14   myFILE* fp = my_fopen("./myfile.txt" , "w");
 15   if(fp == NULL) return 1;           
 16                                      
 17   const char *message = "这就是我的作业\n";
 18                                      
 19   my_fwrite(fp,message,strlen(message));
 20                                      
 21   my_fclose(fp);                     
 22                                      
 23   return 0;                          
 24 }        

我们编译链接一下:
在这里插入图片描述
唉嗨,怎么找不到呢???
因为之前我们使用的库都是C/C++的库,我们的编译器是认识他们的。而我们写的是第三方库,编译器就不认识。所以我们来认识一个新命令:gcc 文件名 -l库名称
需要注意的是库的名称,我们创建的是libmyc.a,那么这里写入的库名称应该是myc ,要去掉lib .a
在这里插入图片描述
这样就可以了!但是我们十分不建议这样做,不要随意改动操作系统的文件。这样很挫!!!

那可不可以不更改操作系统的文件,还想要在当前目录下使用我们的库呢?
我们在系统文件中删除我们的库之后,编译肯定是要报错的因为:
在这里插入图片描述
而此时我们库文件是在mylib中的
在这里插入图片描述
所以gcc就为我们提供了一些选项:

  • -I(大写 i) :可以帮助程序员动态的加入头文件的搜索路径
  • -L :可以帮助程序员动态加入需要链接的库文件的搜索路径
  • -l(小写 L ):指明需要链接的库

来实践一下:
在这里插入图片描述
这样就可以不改变系统文件就完成与静态库的链接!!!

其中-I(大写i) 这个选项也可以不使用,但是前提是在代码中包含的头文件就要指明路径:

#inlcude"../mylib/inlclude/mystdio.h" 
#inlcude"../mylib/inlclude/mymath.h"

注意一定是使用" ",因为< >只会会在系统默认路径下搜索。验证一下:
在这里插入图片描述
我们在回忆一下,我们之前学习gcc的时候说过:

  • -static 此选项对生成的文件采用静态链接
  • shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库

我们在这里并没有指明-static ,怎么就可以使用了呢?因为当前我们的代码里没有动态库,所以编译器就只可以使用静态库了。

  • 编译器默认优先动态链接,没有动态库才会使用静态链接

Thanks♪(・ω・)ノ谢谢阅读!!!

下一篇文章见!!!

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

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

相关文章

ADS基础教程11 - TouchStone文件的导出及导入

目录 一、 T o u c h S t o n e 介绍 \color{#4285f4}{ \mathbf{ 一、TouchStone介绍}} 一、TouchStone介绍 二、文件导出、导入方式 \color{#4285f4}{ \mathbf{ 二、文件导出、导入方式}} 二、文件导出、导入方式1.原理图操作1&#xff09;原理图中导出2.原理图中导入 3.DDW中…

Leetcode—796. 旋转字符串【简单】

2024每日刷题&#xff08;132&#xff09; Leetcode—796. 旋转字符串 实现代码 class Solution { public:bool rotateString(string s, string goal) {return ((s.length() goal.length()) && (s s).find(goal) ! string::npos);} };运行结果 之后我会持续更新&am…

蓝桥杯成绩已出

蓝桥杯的成绩早就已经出来了&#xff0c;虽然没有十分惊艳 &#xff0c;但是对于最终的结果我是心满意足的&#xff0c;感谢各位的陪伴&#xff0c;关于蓝桥杯的刷题笔记我已经坚持更新了49篇&#xff0c;但是现在即将会告别一段落&#xff0c;人生即将进入下一个规划。我们一起…

3---Linux编译器gcc/g++

一、程序的翻译过程&#xff1a;ESc->iso 1.1预处理&#xff1a;c->c 主要功能&#xff1a;宏替换、头文件的展开、条件编译、去注释&#xff1b;目的是让代码变得纯粹。条件编译&#xff0c;可以实现对代码的裁剪。比如对于不同用户&#xff0c;设置不同的宏常量&…

【知识碎片】2024_05_10

每日代码 至少是其他数两倍的最大数 . - 力扣&#xff08;LeetCode&#xff09; int dominantIndex(int* nums, int numsSize) {int max_num 0;int next_max 0;int pos 0;for(int i 0; i < numsSize; i){if(nums[i] > max_num) {pos i;next_max max_num;max_num…

【Linux】简易进度条的实现

&#x1f389;博主首页&#xff1a; 有趣的中国人 &#x1f389;专栏首页&#xff1a; Linux &#x1f389;其它专栏&#xff1a; C初阶 | C进阶 | 初阶数据结构 小伙伴们大家好&#xff0c;本片文章将会讲解Linux中进度条的实现的相关内容。 如果看到最后您觉得这篇文章写得…

LeetCode算法题:7. 整数反转

给你一个 32 位的有符号整数 x &#xff0c;返回将 x 中的数字部分反转后的结果。 如果反转后整数超过 32 位的有符号整数的范围 [−2^31, 2^31 − 1] &#xff0c;就返回 0。 假设环境不允许存储 64 位整数&#xff08;有符号或无符号&#xff09;。 示例 1&#xff1a; 输…

QML配合VTK基本实现

采用 QT5.15 VTK9.2.0 建立QT QUICK项目 部分方法来源于 QML加载VTK main.cpp #include <QGuiApplication> #include <QQmlApplicationEngine>#include <QQuickVTKRenderWindow.h> #include <QQuickVTKRenderItem.h> #include <vtkPolyDataMapp…

使用2G内存求20亿个数字中出现次数最多的N个

又是一个TOP -N的题目 我看了一下CSDN上大多数人的回答和GPT说的差不多&#xff0c;都是说使用哈希之类的&#xff1b; 我今天说一下我的解法&#xff0c;首先说一下不太快的基础解法 20亿数字使用uint32需要80GB&#xff0c; &#xff08;1&#xff09;分为40块读取&#…

百面算法工程师 | 传统图像处理——OpenCV

本文给大家带来的百面算法工程师是传统图像处理的面试总结&#xff0c;文章内总结了常见的提问问题&#xff0c;旨在为广大学子模拟出更贴合实际的面试问答场景。在这篇文章中&#xff0c;我们将介绍一些集几何变换和图像平滑处理&#xff0c;并提供参考的回答及其理论基础&…

中国地面气候资料日值数据获取方式

数据简介 环境气象数据服务平台提供了全国大约2100个点位&#xff0c;2000年至2023年的逐日数据。包括气温、气压、湿度、风、降水等要素。 数据基于ECMWF reanalysis-era5-land、reanalysis-era5-single-levels 以及中国2100站点地面气候资料日值观测数据&#xff0c;使用机器…

深入Android ViewModels:Dos和Don‘ts

深入Android ViewModels&#xff1a;Dos和Don’ts 若你正使用ViewModels&#xff0c;务记以下几点以提升代码质量。本系列文章深入探讨了利用Android ViewModels的最佳实践&#xff0c;强调必须遵循和避免的关键点&#xff0c;以提升代码质量。我们将讨论ViewModels在管理UI状…

HarmonyOS开发案例:【生活健康app之编写通用工具类】(5)

本节将介绍日志打印、时间换算等通用工具类的编写和使用&#xff0c;工具类可以简化应用代码编写和业务流程处理。 日志类 日志类Logger旨在提供一个全局的日志打印、日志管理的地方&#xff0c;既可以规范整个应用的日志打印&#xff0c;也方便日后对日志工具类进行修改&…

CV每日论文--2024.5.9

1、Tactile-Augmented Radiance Fields 中文标题&#xff1a;触觉增强的辐射场 简介&#xff1a;我们提出了一种新的场景表示方法,称为"触觉增强的辐射场(Tactile-Augmented Radiance Fields, TaRF)"。这种方法将视觉和触觉信息融合到一个共享的三维空间中。通过拍摄…

【Vue2】关于response返回数据的错误小记

关于Vue2中response返回数据的一个错误小记 如图&#xff0c;在这里返回的时候&#xff0c;后端是通过List< String >返回的&#xff0c;response接收到的实际上是一个Array数组&#xff0c;但是赋值给searchedTaskList的时候&#xff0c;需要在.then包括的范围里面赋值给…

2024年心理健康与人文发展国际学术会议(ICPHHD 2024)

2024年心理健康与人文发展国际学术会议(ICPHHD 2024) 2024 International Conference on Psychological Health and Humanistic Development 一、【会议简介】 2024年心理健康与人文发展国际学术会议&#xff0c;将汇集全球的心理学家和导师、学者。 在这个盛大的学术会议上&am…

智启未来:富唯智能AI-ICDP引领的可重构柔性装配产线

在全球制造业竞争日益激烈的今天&#xff0c;如何快速响应市场变化、提高生产效率、降低生产成本&#xff0c;成为了企业面临的重要挑战。随着产品个性化时代的到来&#xff0c;装配产品频繁变换&#xff0c;多品种小批量的生产模式逐渐成为主流。在这一背景下&#xff0c;富唯…

msix packaging tool打包问题

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

【Linux】Linux——Centos7安装Tomcat

1.下载Tomcat 安装包 官网地址&#xff1a;Apache Tomcat - Apache Tomcat 9 Software Downloadshttps://tomcat.apache.org/download-90.cgi 2.将下载的安装包上传到 Xftp 上&#xff0c;我是直接放到 usr 下了 3.将安装包解压到 /usr/local/ tar -zxvf apache-tomcat-9.0.8…

google地图js,添加标记,以及infowindow信息弹窗

&#xff08;谷歌地图版本V3&#xff09; var contentString "<div classdevinfo><P>设备ID: BJ-20240507</p> <P>设备状态: 正常</p> <P>通讯信号: 89% </p> <P>设备位置: 中国</p> <P>剂量率: 988</p&…