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

在这里插入图片描述

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

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


从零开始认识动静态库

  • 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♪(・ω・)ノ谢谢阅读!!!

下一篇文章见!!!

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

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

相关文章

mysql数据库调优篇章1--日志篇

目录 1.认识数据库中日志的作用2.增加mysql数据库中my.ini 基本配置3.增加my.ini中参数配置4.查看已经执行过的sql语句过去执行时间5.找出慢查询的sql6.常用参数查询命令7.认识慢查询日志记录8.认识通用日志记录&#xff08;记录增删改查操作&#xff09;9.认识二进制文件binlo…

多维点分布的均匀性评估方法(NDD和Voronoi 图法)

评估多维点分布的均匀性是统计学和数据科学中的一个重要问题&#xff0c;特别是在模拟、空间分析和样本设计等领域。下面&#xff0c;我将详细介绍2种评估多维点分布均匀性的方法&#xff0c;包括它们的数学原理、实现公式以及各自的优缺点。 1. 最近邻距离法&#xff08;Neare…

CTF例题和知识点

[ACTF2020 新生赛]Include 打开靶机发现一个超链接&#xff0c;点击之后出现一段话 “Can you find out the flag?” 查看源码注入&#xff0c;无果 仔细看url&#xff0c;发现有flag.php 根据题目提示&#xff0c;该题应该是文件包含漏洞&#xff0c;因此可以判断出此题是PH…

通俗的理解网关的概念的用途(三):你的数据包是如何到达下一层的

其实&#xff0c;这一章我写不好&#xff0c;因为这其中会涉及到一些计算和一些广播等概念&#xff0c;本人不善于此项。在此略述&#xff0c;可以参考。 每台设备的不同连接在获得有效的IP地址后&#xff0c;会根据IP地址的规则和掩码的规则&#xff0c;在操作系统和交换机&a…

自动控制原理学习--平衡小车的控制算法(三)

上一节PID的simulin仿真&#xff0c;这一节用LQR 一、模型 二、LQR LQR属于现代控制理论的一个很重要的点&#xff0c;这里推荐B站的【Advanced控制理论】课程&#xff08;up主DR_CAN&#xff09;&#xff0c;讲得很好&#xff0c;这里引用了他视频里讲LQR的ppt。 LQR属于lo…

车载电子电器架构 —— 应用软件开发(中)

车载电子电器架构 —— 应用软件开发(中) 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明…

医疗行业如何提升Windows操作系统登录的安全性

医疗行业使用账号和密码登录Windows系统时&#xff0c;可能会遇到一些痛点&#xff0c;这些痛点可能会影响工作效率、数据安全和用户体验。以下是一些主要的痛点&#xff1a; 1. 密码管理复杂性&#xff1a;医疗行业通常涉及大量的敏感数据和隐私信息&#xff0c;因此密码策略…

非模块化 Vue 开发的 bus 总线通信

个人感觉&#xff0c;JavaScript 非模块开发更适合新人上手&#xff0c;不需要安装配置一大堆软件环境&#xff0c;不需要编译&#xff0c;适合于中小项目开发&#xff0c;只需要一个代码编辑器即可开发&#xff0c;例如 vsCode。网页 html 文件通过 script 标签引入 JavaScrip…

学习笔记——字符串(单模+多模+练习题)

单模匹配 Brute Force算法&#xff08;暴力&#xff09; 算法思想 母串和模式串字符依次配对&#xff0c;如果配对成功则继续比较后面位置是否相同&#xff0c;如果出现匹配不成功的位置&#xff0c;则j&#xff08;模式串当前的位置&#xff09;从头开始&#xff0c;i&…

中北大学软件学院javaweb实验二JSP应用开发实验报告

实验时间 2024年4月 25 日17时至 22 时 学时数 4 1.实验名称 实验2&#xff1a;JSP应用开发(2学时) 2.实验目的 &#xff08;1&#xff09;学会编写和运行简单的JSP页面&#xff0c;理解其运行原理&#xff1b; &#xff08;2&#xff09;学会使用JSP的声明、表达式、脚…

中国211大学全部排名一览表

211大学是指中国教育部实施的名为“211工程”的高等教育发展战略中被选为重点支持的高等院校。这个名称来源于项目的启动背景和目标&#xff1a;“211”中的“21”代表21世纪&#xff0c;意味着该项目面向21世纪的中国高等教育发展&#xff1b;“1”则意指要重点建设大约100所左…

126.删除链表的倒数第N个节点(力扣)

题目描述 代码解决&#xff08;双指针&#xff09; /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, Li…

C语言实现扫雷游戏完整版

游戏介绍&#xff1a; 目录 游戏介绍&#xff1a; 游戏框架&#xff1a; 游戏具体功能实现&#xff1a; 棋盘的定义&#xff1a; 棋盘初始化&#xff1a; 棋盘打印&#xff1a; 棋盘布置雷&#xff1a; 棋盘扫雷&#xff1a; 爆炸展开一片&#xff1a; 获取周围八个…

画出入学管理系统的顶层图和1层图

&#xff08;学校作业&#xff09; 题目如下&#xff1a; 某培训机构入学管理系统有报名、交费和就读等多项功能&#xff0c;下面是对其各项功能的说明&#xff1a; 1、报名&#xff1a;由报名处负责&#xff0c;需要在学员登记表上进行报名登记&#xff0c;需要查询课…

Kettle连接Mysql数据库时报错——Driver class ‘org.gjt.mm.mysql.Driver‘ could not be found

一、问题描述 当我们使用ETL工具Kettle需要连接Mysql数据库进行数据清洗操作,在配置好Mysql的连接串内容后,点击【测试】按钮时报错【错误连接数据库 [MysqlTestConnection] : org.pentaho.di.core.exception.KettleDatabaseException: Error occurred while trying to conne…

记一次DNS故障导致用户无法充值的问题(下)

上一篇说到DNS故障导致无法充值&#xff0c;后来我们通过拨测发现业务域名的解析目标地址被解析到了【127.0.0.1】IP。 1、联系阿里云厂商&#xff0c;通过沟通&#xff0c;阿里云反馈我们的域名被XX省通管单位封禁了&#xff0c;导致解析到了不正确的地址。 2、为了解决用户问…

idea运行SpringBoot项目爆红提示出现:Java HotSpot(TM) 64-Bit Server VM warning...让我来看看~

在运行SpringBoot项目的时候&#xff0c;发现总有这个警告提示出现&#xff0c;有点强迫症真的每次运行项目都很难受啊&#xff01;那么今天便来解决这个问题&#xff01; 先来看一下提示内容&#xff1a;Java HotSpot(TM) 64-Bit Server VM warning: Options -Xverify:none an…

多目标跟踪入门介绍

多目标跟踪算法 我们也可以称之为 Multi-Target-Tracking &#xff08;MTT&#xff09;。 那么多目标跟踪是什么&#xff1f; 不难看出&#xff0c;跟踪算法同时会为每个目标分配一个特定的 id 。 由此得出了目标跟踪与目标检测的区别&#xff08;似乎都是用方框来框出目标捏…

树与二叉树之间的转换

树转化成二叉树&#xff1a;兄弟相连留长子 1.加线&#xff1a;在兄弟之间加一条线 2.抹线&#xff1a;对每个结点&#xff0c;除了其左孩子外&#xff0c;去除其与其余孩子之间的关系 3.旋转&#xff1a;以树的根结点为轴心&#xff0c;将整树顺时针转45 二叉树转化成为树…

云衔科技成为卓豪Zoho中国区代理商,开启智能化企业管理新篇章

每一家企业数字化转型&#xff0c;都在寻求通过技术创新实现业务的飞跃。为了更好地服务于中国企业的数字化转型需求&#xff0c;云衔科技荣幸宣布正式成为卓豪Zoho中国区代理商&#xff0c;这一强强联合将为市场带来全新的数字化解决方案与服务体验&#xff0c;共同开启中国企…