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

下一篇文章见!!!

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

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

相关文章

Linux虚拟机运行“yum install gcc-c++”报错“Loading mirror speeds from cached hostfile”

目录 一、在Linux上安装Redis时&#xff0c;在终端执行命令“yum install gcc-c”时&#xff0c;报错&#xff1a; 二、然后发现linux的网络不通&#xff0c;什么网站都访问不了 三、连上网后&#xff0c;再变换yum源 四、重新运行yum install gcc 一、在Linux上安装Redis时…

Java中55种锁,高级面试题,最新面试题

Java中乐观锁在实际应用中如何解决并发问题&#xff1f; 乐观锁通过假设并发冲突发生概率较低来解决并发问题&#xff0c;主要通过数据版本控制实现。在更新数据前&#xff0c;会检查数据版本是否发生变化&#xff0c;只有在数据版本未变时才允许更新&#xff0c;这样可以避免…

nginx_01

1.安装 yum install epel-release -y # 安装yum的扩展包 yum install nginx -y systemctl start nginx.service #启动nginx systemctl enable nginx.service # netstat -lntup # 查看端口占用情况 # 可以看到nginx默认占用了80端口 2.nginx配置 # 注意配置文件的语法格式…

万物生长大会 | 创邻科技再登杭州准独角兽榜单

近日&#xff0c;由民建中央、中国科协指导&#xff0c;民建浙江省委会、中国投资发展促进会联合办的第八届万物生长大会在杭州举办。 在这场创新创业领域一年一度的盛会上&#xff0c;杭州市创业投资协会联合微链共同发布《2024杭州独角兽&准独角兽企业榜单》。榜单显示&…

小红书搞钱美学课-6.0升级版,账号搭建/爆款创作/工具实战/账号变现篇

让我们用视觉撬动流量 课程体系 334253课程权益(5周服务期) 3节账号运营基础课3节自媒体笔记创作课。4节封面设计实操课2次实操加餐分享5次作业指导(一对一)3次答疑直播 课程大纲 一、账号搭建篇 变现模板、精准定位 二、爆款创作篇爆款选题、首图、文案与脚本、快速涨粉…

【计算机毕业设计】springboot工资管理系统

人类现已迈入二十一世纪&#xff0c;科学技术日新月异&#xff0c;经济、资讯等各方面都有了非常大的进步&#xff0c;尤其是资讯与 网络技术的飞速发展&#xff0c;对政治、经济、军事、文化等各方面都有了极大的影响。 利用电脑网络的这些便利&#xff0c;发展一套工资管理系…

权力集中,效率提升,中心化模式的优势与挑战

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 &#x1f680; 转载自热榜文章&#x1f525;&#xff1a;探索设计模式的魅力&#xff1a;权力集中…

IO 5.10

在一个进程中&#xff0c;创建一个子线程。 主线程负责&#xff1a;向文件中写入数据 子线程负责&#xff1a;从文件中读取数据 要求使用线程的同步逻辑&#xff0c;保证一定在主线程向文件中写入数据成功之后&#xff0c;子线程才开始运行&#xff0c;去读取文件中的数据#incl…

学习java的继承

1.什么是继承 java中提供了一个关键字&#xff0c;extends&#xff0c;可以让一个类与另一个类建立起父子关系。 例如 public class B extends A { --- } 在这里&#xff0c;我们称A类为父类&#xff08;也被称为基类或者超类&#xff09;B类称为子类&#xff08;或者是派生…

debian10 (armbian) 配置CUPS 服务

更新apt apt-update安装相关软件 apt-get install ghostscript apt-get install dc apt-get install foomatic-db-engine apt-get install cups3.修改配置文件 nano /etc/cups/cupsd.conf Listen localhost:631改为 Listen 0.0.0.0:631 以下四段配置加入Allow All # Only li…

【智能优化算法】矮猫鼬优化算法(Dwarf Mongoose Optimization Algorithm,DMHO)

矮猫鼬优化算法(Dwarf Mongoose Optimization Algorithm,DMHO)是期刊“COMPUTER METHODS IN APPLIED MECHANICS AND ENGINEERING”&#xff08;IF 7.3&#xff09;的2022年智能优化算法 01.引言 矮猫鼬优化算法(Dwarf Mongoose Optimization Algorithm,DMHO)模仿矮猫鼬的觅食行…

天府锋巢直播产业基地构建成都电商直播高地

天府锋巢直播产业基地自成立以来&#xff0c;一直秉承着创新、协同、共赢的发展理念&#xff0c;吸引了众多直播企业纷纷入驻。随着直播产业的迅猛发展&#xff0c;改成都直播基地内的配套服务也显得尤为重要。本文将深入探讨入驻天府锋巢直播产业基地后&#xff0c;配套的直播…

错误处理机制——vba(vb.net)

程序出现错误时可采用如下错误处理机制&#xff1a;出错时跳到标签处&#xff0c;判断错误类型修正错误&#xff0c;重新返回正确标签处&#xff0c;继续运行程序。 代码如下&#xff1a; Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click…

Golang面向对象编程(一)

文章目录 结构体基本介绍结构体定义方式创建结构体变量结构体内存对齐结构体类型转换字段的Tag标签 方法基本介绍方法的定义和调用方法调用的传参机制String方法 结构体 基本介绍 基本介绍 Go支持面向对象编程特性&#xff0c;包括封装、继承和多态&#xff0c;但Go中没有类&a…

Linux——综合实验

要求 按照上面的架构部署一个简单的web节点所有的服务器使用DNS服务器作为自己的DNS服务器 就是/etc/reslov.conf 中nameserver的值必须是途中dns服务器的地址所有的数据库都是用mysql应用 nfs共享导出在客户端(web服务器上)使用autofs在自动挂载&#xff0c;或者写入/etc/fsta…

window10设置静态IP

右键桌面网络图标 点击属性 点击要查看的网络 点击详细信息 获得网络连接详细信息 右键WiFi符号 或者其他方式进入网络与internet中心 点击 WLAN 点击属性 点击编辑&#xff08;点击一个即可&#xff09; 选择手动将刚才的信息方进入即可 完成

MySQL变量的声明与使用

MySQL变量的声明与使用 1、标识符不能以数字开头 2、自能使用_或$符号&#xff0c;不允许使用其他符号。 3、不允许使用系统关键字 将赋值与查询结合 set userName 刘德华; select userName: 刘青云; # 将赋值与查询结合 查询变量/使用变量 select userName as 读取到的u…

TDN: Temporal Difference Networks for Efficient Action Recognition 论文阅读

TDN: Temporal Difference Networks for Efficient Action Recognition 论文阅读 Abstract1. Introduction2. Related work3. Temporal Difference Networks3.1. Overview3.2. Short-term TDM3.3. Long-term TDM3.4. Exemplar: TDN-ResNet 4. ExperimentsAblation studiesCompa…

抖音新店怎么对接达人?对接达人秘籍流程分享,让你学会找达人

大家好&#xff0c;我是电商花花。 新手怎么对接达人带货&#xff1f;这是我们新手商家 要考虑的问题。 很多新手抱怨自己新店铺不出单&#xff0c;没有销量&#xff0c;对接达人又怕达人看不上&#xff0c;没有达人愿意帮我带货&#xff0c;在面临这样的情况下不知道该怎么办…

【科研】常用的实验结果评价指标(1) —— R2(R-square)是什么?

常用的实验结果评价指标&#xff08;1&#xff09; —— R2(R-square)&#xff0c;可能为负数吗&#xff1f;&#xff01; 提示&#xff1a;先说概念&#xff0c;后续再陆续上代码 文章目录 常用的实验结果评价指标&#xff08;1&#xff09; —— R2(R-square)&#xff0c;可能…