Linux 的静态库和动态库

news2024/12/24 0:16:54

本文目录

  • 一、静态库
    • 1. 创建静态库
    • 2. 静态库的使用
  • 二、动态库
    • 1. 为什么要引入动态库呢?
    • 2. 创建动态库
    • 3. 动态库的使用
    • 4. 查看可执行文件依赖的动态库

  

一、静态库

   在编译程序的链接阶段,会将源码汇编生成的目标文件.o与引用到的库(包括静态库)的二进制文件一起链接打包到最终的可执行文件中。

静态库常以.a.lib为后缀。
   静态库命名规范:lib[name].a,其中lib是静态库前缀,中间[name]为静态库名称,最后.a为静态库后缀。例如:libaddfunc.a,其中addfunc才是静态库的名称。

1. 创建静态库

   在使用创建静态库前,为了使得工程目录更加清晰,我们创建三个文件夹lib(存放.h文件)、src(存放.c文件)、debug(存放.o文件)

(1)编写库文件。
fun1.c

#include "stdio.h"

int add(int a, int b)
{
  return a+b;
}

fun1.h

#include "stdio.h"

int add(int a, int b);

将编写好的库文件存放到不同的文件夹里。

(2)将库文件编译为目标文件(.o)
  使用命令:gcc -c ./src/fun1.c -o ./debug/fun1.o,在debug目录下生成fun1.o目标文件。

(3)创建封装静态库
  使用ar工具,并添加命令 rcs,将debug文件夹里的所有的.o文件进行封装为静态库libaddfunc.a
  如:ar rcs libaddfunc.a ./debug/*.o。此时libaddfunc.a就是静态库。其中addfunc是静态库的名称。
在这里插入图片描述

2. 静态库的使用

(1)编写main.c源码文件

main.c

#include "fun1.h"
#include "stdio.h"

int main()
{
  int a=8;
  int b=10;
  int sum=0;
  sum=add(a,b);
  printf("%d\n"sum);
}

(2)编译源码时链接静态库,生成可执行文件。
  命令:gcc main.c -o main -I ./lib -L ./ -l addfunc
   -I ./lib :表示头文件所在的路径。
   -L ./ :表示静态库所在的路径,此处为当前路径。
   -l addfunc:表示要连接的静态库名称,addfunc为静态库名称。

在这里插入图片描述

(3)运行可执行文件。
在这里插入图片描述

二、动态库

   在程序编译时并不会被链接到目标代码中,而是在程序运行时才被载入。

动态库常以.so.dll为后缀。
   动态库命名规范:lib[name].a,其中lib是动态库前缀,中间[name]为动态库名称,最后.so为动态库后缀。例如:libsubfunc.so,其中subfunc才是动态库的名称。

1. 为什么要引入动态库呢?

   答:因为在静态库存在一个弊端,就是当我们对库文件添加或修改了部分内容,将其生成新的静态库文件后,我们需要将所有使用该库文件的程序文件都要重新编译。因为当静态库修改后,其二进制文件也会改变。静态库在程序编译链接阶段,将字节的二进制文件一同打包到程序的可执行文件中。所以静态库改变后,需要将使用了该静态库的可执行文件都需要重新进行编译。这样就会特别繁琐,所以引入了动态库。
   动态库只会在程序运行时载入。动态库作为一个独立的文件存在于系统中,可以被多个文件共享使用,当动态库进行维护时,只需要将新的动态库文件替换旧的动态库文件即可,不需要对使用动态库的文件程序重新编译,这就是动态库的好处。

2. 创建动态库

举例使用的库文件我们使用上述静态库时的库文件。同样存放到不同的文件夹中。

(1)将库文件生成目标文件(.o)

  使用命令:gcc -fpic -c ./src/fun1.c -o ./debug/fun1.o,在debug目录下生成fun1.o目标文件。

(2)生成动态库–共享库
  使用命令:gcc -shared ./debug/*.o -o libfun2.so。其中libfun2.so为动态链接库,也称共享库。
在这里插入图片描述

3. 动态库的使用

(1)编译源码,生成可执行文件
使用命令:gcc main.c -o main -I ./lib -L ./ -l fun2
   -I ./lib :表示头文件所在的路径。
   -L ./ :表示动态库所在的路径,此处为当前路径。
   -l addfunc:表示要连接的动态库名称。
在这里插入图片描述
  虽然这里我们也指定了动态库的路径,但是动态库在编译可执行文件时并不会进行链接,而是在执行时才会进行链接!所以当我们维护动态库时,才不会对所使用动态库的文件进行重新编译。

(2)将库路径添加到系统加载器
   生成的可执行文件,当我们执行时,会发生以下错误,原因是我们虽然告诉了编译器库文件和头文件的路径所在位置,但是当编译器编译好后,就与编译器无关了;当我们执行(运行)可执行程序时,是由加载器来完成的。所以我们需要在运行时,告诉系统库文件在哪里。
在这里插入图片描述

 方法一:将libfun2.so添加到/usr/lib/下, 使用命令:sudo cp libfun2.so /usr/lib/进行添加。不推荐!
 方法二:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/qjl , LD_LIBRARY_PATH环境变量用于在程序加载运行期间查找动态链接库时指定除了系统默认路径之外的其他路径。
在这里插入图片描述

(3)运行可执行文件
在这里插入图片描述

4. 查看可执行文件依赖的动态库

使用命令:ldd 可执行文件
在这里插入图片描述

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

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

相关文章

2024小米SU7首批锁单用户调研报告

来源:电动汽车用户联盟 80%的锁单用户认为自己是米粉,64%的用户拥有10个以上米家生态产品, 使用小米手机的比例为67%,使用苹果手机的比例为47% 2. 81%的用户为90后,均龄31岁,未婚者和已婚无孩者占比63%&am…

接口测试 - postman

文章目录 一、接口1.接口的类型2. 接口测试3. 接口测试流程4. 接口测试用例1. 测试用例单接口测试用例-登录案例 二、HTTP协议1. HTTP请求2. HTTP响应 三、postman1. 界面导航说明导入 导出用例集 Get请求和Post请求的区别:2.postman环境变量和全局变量3. postman 请求前置脚本…

Java微服务分布式分库分表ShardingSphere - ShardingSphere-JDBC

🌹作者主页:青花锁 🌹简介:Java领域优质创作者🏆、Java微服务架构公号作者😄 🌹简历模板、学习资料、面试题库、技术互助 🌹文末获取联系方式 📝 往期热门专栏回顾 专栏…

【算法刷题 | 贪心算法05】4.27(K次取反后最大化的数组和、加油站)

文章目录 8.K次取反后最大化的数组和8.1题目8.2解法:贪心8.2.1贪心思路8.2.2代码实现 9.加油站9.1题目9.2解法:贪心9.2.1贪心思路9.2.2代码实现 8.K次取反后最大化的数组和 8.1题目 给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数…

基于EBAZ4205矿板的图像处理:03使用VIO调试输出HDMI视频图像

基于EBAZ4205矿板的图像处理:03使用VIO调试输出HDMI视频图像 在zynq调试时VIO是真的方便,特此写一篇博客记录一下 先看效果 项目简介 下面是我的BD设计,vtc用于生成时序,注意,2021.2的vivado的vtcIP是v6.2版本&…

【算法】【贪心算法】【leetcode】870. 优势洗牌

题目地址:https://leetcode.cn/problems/advantage-shuffle/description/ 题目描述: 给定两个长度相等的数组 nums1 和 nums2,nums1 相对于 nums2 的优势可以用满足 nums1[i] > nums2[i] 的索引 i 的数目来描述。 返回 nums1 的任意排列&…

C++入门基础(二)

目录 缺省参数缺省参数概念缺省参数分类全缺省参数半缺省参数声明与定义分离 缺省参数的应用 函数重载函数重载概念例子1 参数类型不同例子2 参数的个数不同例子3 参数的顺序不同 C支持函数重载的原理--名字修饰(name Mangling) 感谢各位大佬对我的支持,如果我的文章对你有用,欢…

nginx+Tomcat动静分离

本⽂的动静分离主要是通过nginxtomcat来实现,其中nginx处理图⽚、html等静态的⽂ 件,tomcat处理jsp、do等动态⽂件. 实验环境 192.168.200.133 nginx反向代理 192.168.200.129 static 192.168.200.130 dynamic 步骤 修改三台主机名 [rootadmin ~]#…

《Redis使用手册之列表》

《Redis使用手册之列表》 目录 **《Redis使用手册之列表》****LPUSH:将元素推入列表左端****LPUSHX、RPUSHX:只对已存在的列表执行推入操作****LPOP:弹出列表最左端的元素****RPOP:弹出列表最右端的元素****RPOPLPUSH:…

【C语言刷题系列】删除公共元素

目录 一、问题描述 二、解题思路 三、源代码实现 解决方案一:拷贝到临时数组 解决方案二:直接打印 个人主页: 倔强的石头的博客 系列专栏 :C语言指南 C语言刷题系列 一、问题描述 二、解题思路 第一种方法&…

线上告警炸锅!FastJson 又立功了。。

前段时间新增一个特别简单的功能,晚上上线前review代码时想到公司拼搏进取的价值观临时加一行log日志,觉得就一行简单的日志基本上没啥问题,结果刚上完线后一堆报警,赶紧回滚了代码,找到问题删除了添加日志的代码&…

3.C++动态内存管理(超全)

目录 1 .C/C 内存分布 2. C语言中动态内存管理方式:malloc/calloc/realloc/free 3. C内存管理方式 3.1 new/delete操作内置类型 3.2 new和delete操作自定义类型 3.3 operator new函数 3.4 定位new表达式(placement-new) (了解) 4. 常…

iA Writer for Mac:简洁强大的写作软件

在追求高效写作的今天,iA Writer for Mac凭借其简洁而强大的功能,成为了许多作家、记者和学生的首选工具。这款专为Mac用户打造的写作软件,以其独特的设计理念和实用功能,助你轻松打造高质量的文章。 iA Writer for Mac v7.1.2中文…

C语言(操作符)1

Hi~!这里是奋斗的小羊,很荣幸各位能阅读我的文章,诚请评论指点,关注收藏,欢迎欢迎~~ 💥个人主页:小羊在奋斗 💥所属专栏:C语言 本系列文章为个人学习笔记&#x…

vue2迁移到vue3,v-model的调整

项目从vue2迁移到vue3,v-model不能再使用了,需要如何调整? 下面只提示变化最小的迁移,不赘述vue2和vue3中的常规写法。 vue2迁移到vue3,往往不想去调整之前的代码,以下就使用改动较小的方案进行调整。 I…

Java并发编程面试问题与答案

1. 什么是线程安全? 答: 线程安全意味着多个线程可以同时访问一个类的实例而不引起任何问题或不一致的结果。线程安全的代码会通过同步机制来确保所有线程都能正确地访问共享资源。 2. 解释Java中的synchronized关键字。 答: synchronized…

Q1营收稳健增长,云从科技如何在“百模大战”的险中求稳?

自从迈入大模型时代,AI行业可谓“一天一个样”。越来越多的企业涌现,舆论热议从未断绝。 但就像所有技术必须经历的那些考验,在现实尺度下,AI顺利走进商业化世界,仍然是少部分玩家掌握的稀缺能力。个中原因不尽相同&a…

解决“未能正确加载QtVsToolPackage包“问题

今天,在使用VS2019Qt插件时,弹出"未能正确加载QtVsToolPackage包"错误,如图(1.1)所示: 图(1.1) 报"未能正确加载QtVsToolsPackage包"错误 出现这种现象的原因是: qt-vsaddin升级失败或者版本不兼容&#xff0…

动手学深度学习3.6 softmax回归的从零开始实现-笔记练习(PyTorch)

以下内容为结合李沐老师的课程和教材补充的学习笔记,以及对课后练习的一些思考,自留回顾,也供同学之人交流参考。 本节课程地址:Softmax 回归从零开始实现_哔哩哔哩_bilibili 本节教材地址:3.6. softmax回归的从零开…

物联网实战--平台篇之(二)基础搭建

目录 一、Qt工程创建 二、数据库知识 三、通信协议 四、名词定义 本项目的交流QQ群:701889554 物联网实战--入门篇https://blog.csdn.net/ypp240124016/category_12609773.html 物联网实战--驱动篇https://blog.csdn.net/ypp240124016/category_12631333.html 一、Qt工程…