Linux系统基础-动静态库

news2024/11/24 18:37:46

个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创

Linux系统基础-动态库和静态库

收录于专栏[Linux学习]
本专栏旨在分享学习Linux的一点学习笔记,欢迎大家在评论区交流讨论💌

目录

1. 动静态库的概念

2. 生成静态库

3. 生成动态库

4. 使用静态库

5. 使用动态库

6. 使用外部库 

7.  动态库加载

8. 总结

动态库与静态库的优缺点总结: 

1. 静态库

2. 动态库 

动态库和静态库使用场景总结: 

1. 静态库的使用场景

2. 动态库的使用场景


1. 动静态库的概念

静态库(.a) : 程序在编译链接的时候把库的代码链接到可执行文件中, 程序运行的时候将不在需要静态库

动态库(.so) : 程序在运行的时候才去链接动态库的代码, 多个程序共享使用库的代码.

我们可以使用ldd查看一个程序所连接的库:

可以看到我们简单一个C语言程序连接了三个库 

补充:

1. 一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表, 而不是外部函数所在目标文件的整个机械码

2. 在可执行文件开始运动以前, 外部函数的机械码由操作系统从磁盘上的动态库中复制到内存中, 这个过程称为动态链接 (dynamic linking)

3. 动态库可以在多个程序间共享, 所以动态链接使得可执行文件更小, 节省了磁盘空间, 操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用, 节省了内存和磁盘空间 

2. 生成静态库

测试程序: 

add.h
#ifndef __ADD_H__
#define __ADD_H__
int add(int a, int b);
#endif // __ADD_H__

sub.h
#ifndef __SUB_H__
#define __SUB_H__
int sub(int a, int b);
#endif // __SUB_H__

add.c
#include "add.h"
int add(int a, int b)
{
    return a + b;
}

sub.c
#include "add.h"
int sub(int a, int b)
{
    return a - b;
}

main.c
#include <stdio.h>
#include "add.h"
#include "sub.h"

int main()
{
    int a = 10;
    int b = 20;
    printf("add(%d, %d)=%d\n", a, b, add(a, b));
    a = 100;
    b = 20;
    printf("sub(%d,%d)=%d\n", a, b, sub(a, b));
    return 0;
}

 直接运行结果:

生成静态库:

所谓的库文件, 本质, 就是把.o打包

ar是gnu归档工具,rc表示(replace and create)

查看静态库中的目录列表, t:列出静态库中的文件 v:verbose 详细信息 

 

3. 生成动态库

shared: 表示生成共享库格式

fPIC:产生位置无关码(position independent code)

库名规则:libxxx.so

4. 使用静态库

-L 指定库路径 -l 指定库名

测试目标文件生成后,静态库删掉,程序照样可以运行 

库搜索路径 :

从左到右搜索-L指定的目录.

由环境变量指定的目录 (LIBRARY_PATH)

由系统指定的目录

1. /usr/lib

2. /usr/lical/lib

5. 使用动态库

编译选项:

l:链接动态库,只要库名即可(去掉lib以及版本号)

L:链接库所在的路径

6. 使用外部库 

系统中其实有很多库,它们通常由一组互相关联的用来完成某项常见工作的函数构成。比如用来处理屏幕显示情况的函数(ncurses库) 

下载ncurses库

sudo apt update
sudo apt install libncurses5-dev libncursesw5-dev

 示例代码:

#include <math.h>
#include <stdio.h>
int main(void)
{
    double x = pow(2.0, 3.0);
    printf("The cubed is %f\n", x);
    return 0;
}

-lm表示要链接libm.so或者libm.a库文件 

库文件名称和引入库的名称

如:libc.so -> c库,去掉前缀lib,去掉后缀.so,.a 

7.  动态库加载

 

动态库在加载之后, 要映射在当前进程的堆栈之间的共享区

动态库也叫做共享库!!

8. 总结

动态库要在程序运行的时候, 要找到动态库加载并运行!

静态库为什么没有这个问题? 因为静态库编译期间已经将库中的代码拷贝到我们的可执行文件内部了, 加载和库就没有关系了~

动态库 VS 静态库

默认连接的是动态库, 如果你没有使用-static, 并且只提供.a, 只能静态链接当前的.a库, 其他库正常动态链接

-static的意义是什么呢? 必须强制将我们的程序静态连接, 这就要求我们来凝结的任何库都必须提供对应的静态库版本~~

动态库与静态库的优缺点总结: 

1. 静态库

优先: 

1. 执行效率高 : 静态库在编译时直接连接到可执行文件中, 因此程序在运行时不需要加载库文件, 通常会有更快的启动时间和执行效率.

2. 部署简单: 将所有代码打包为一个可执行文件, 不需要在运行时依赖外部库, 简化了部署过程

3. 版本控制: 不受外部库版本的影响, 避免了库更新造成的问题

缺点: 

1. 文件大小大: (上文也有所展示)因为将库的代码复制到每个可执行文件中, 导致生成的可执行文件体积较大, 占用很大内存

2. 更新困难 : 如果需要修复静态库中的bug或添加新特性, 需要重新编译有所依赖该库的可执行文件

3. 资源浪费 : 如果多个程序使用相同的静态库, 它们会各自包含一份库的副本, 占用更多的磁盘和内存空间

2. 动态库 

优先: 

1. 节省内存 : 多个进程可以共享同一个动态库的副本, 减少了内存使用

2. 更新方便 : 只需要替换动态库文件, 无需重新编译依赖该库的应用程序, 便于维护和更新

3. 启动速度快 : 可以在程序运行时按需加载库, 减少初始加载时间

缺点: 

1. 运行时依赖 : 程序运行时需要依赖动态库, 缺失动态库会导致程序无法运行.

2. 调试复杂 : 由于动态连接, 调试过程可能会更加复杂, 特别是在库的版本不兼容时.

3. 加载开销 : 动态库在运行时需要加载, 可能会导致启动时间延长

动态库和静态库使用场景总结: 

1. 静态库的使用场景

1. 小型项目 : 对于小型项目或工具, 使用静态库可以简化构建和部署流程.

2. 不频繁更新的库 : 当库功能稳定且不需要频繁更新时, 使用静态库是合法的

3. 性能要求高的应用 : 在对性能有严格要求的场景下, 静态库可能更具有优势

2. 动态库的使用场景

1.大型应用程序 : 在大型系统中, 使用动态库可以减少内存占用, 特别是当多个程序共享一个库时

2. 频繁更新的库 : 当库需要频繁更新, 且不希望重新编译所有应用时, 动态库是更好的选择.

3. 插件系统 : 在需要实现插件架构的应用中, 动态库允许程序在运行时加载和卸载插件

4. 跨平台开发 : 动态库在不同平台上的使用可以更灵活, 特别是在使用不同版本的依赖时.

 

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

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

相关文章

如何在 Jupyter Notebook 执行和学习 SQL 语句(下)—— 进阶版题目综合(多表连接,窗口函数,子查询等等)

这是我收藏的一些相关的题目&#xff0c;其中包含基本操作&#xff08;如创建表、插入数据&#xff09;&#xff08;注意一般企业也不会让删除数据啥的&#xff0c;毕竟刚进去哪会让对人家数据库做什么操作&#xff0c;我是实习的时候参加了数据仓库的建设&#xff0c;插了一些…

498.对角线遍历

目录 题目解法代码说明&#xff1a;输出&#xff1a; 如何确定起始点&#xff1f;解释一下max(0,d−m1)是什么意思&#xff1f; 如何遍历对角线&#xff1f;.push_back是怎么用的&#xff1f; 题目 给你一个大小为 m x n 的矩阵 mat &#xff0c;请以对角线遍历的顺序&#xf…

JNA调用c++动态库返回数据

jna学习网站 JNA Examples 1、返回String, pch.h头文件 // pch.h: 这是预编译标头文件。 // 下方列出的文件仅编译一次&#xff0c;提高了将来生成的生成性能。 // 这还将影响 IntelliSense 性能&#xff0c;包括代码完成和许多代码浏览功能。 // 但是&#xff0c;如果此处…

软考攻略/超详细/系统集成项目管理工程师/基础知识分享18

6.5数据分析及应用 6.5.1 数据集成&#xff08;掌握&#xff09; 数据集成就是将驻留在不同数据源中的数据进行整合&#xff0c;向用户提供统一的数据视图&#xff0c;使得用户能以透明的方式访问数据。 WebServices技术是一个面向访问的分布式计算模型&#xff0c;它的本质是…

Nature 正刊丨空间蛋白质组学确定JAKi是一种致命皮肤病的治疗方法

01摘要 中毒性表皮坏死松解症&#xff08;TEN&#xff09;是一种由常见药物引发的致命药物性皮肤反应&#xff0c;是一个新出现的公共卫生问题1,2,3。TEN患者会因角质形成细胞死亡而发生严重和突然的表皮脱离。尽管已经提出了驱动角质形成细胞死亡的分子机制&#xff0c;但主要…

10.21 IO进程直接的通信

1、用消息队列实现两个进程直接的通信 先输入的代码 #include<myhead.h> //定义消息列队的结构体 struct msgbuf {long mtype; //消息类型char mtext[1024]; //消息正文 };//宏定义正文的大小 #define MSGSZ (sizeof(struct msgbuf) - sizeof(long))//定义回收僵尸信号…

Linux第一讲:Linux基本指令

Linux第一讲&#xff1a;Linux基本指令 1.Linux发展历史2.先快速了解一些指令3.指令 -- ls3.1知识点1 -- 文件属性3.1.1详细解析ls指令3.1.1.1 ls3.1.1.2 ls -l 、ls -a3.1.1.2.1 ls -l3.1.1.2.2 ls -a3.1.1.2.3 ls -la 3.1.1.3其它指令 3.2知识点2 -- 什么是.和..3.3知识点3 -…

手写模拟Spring的基本功能

文章目录 1. Spring的基本功能2. 容器启动 容器启动&#xff0c;即创建容器对象并赋予配置对象3. BeanDefinition扫描4. Bean的生命周期5. 单例Bean与多例Bean6. 依赖注入7. AOP8. Aware 回调9. 初始化10. BeanPostProcessor附录&#xff1a; 1. Spring的基本功能 2. 容器启动 …

【鸡翅Club】项目启动

一、项目背景 这是一个 C端的社区项目&#xff0c;有博客、交流&#xff0c;面试学习&#xff0c;练题等模块。 项目的背景主要是我们想要通过面试题的分类&#xff0c;难度&#xff0c;打标&#xff0c;来评估员工的技术能力。同时在我们公司招聘季的时候&#xff0c;极大的…

mingw64的Windows安装及配置教程gcc、g++等

mingw64.rar 链接&#xff1a;https://pan.baidu.com/s/18YrDRyi5NHtqnTwhJG6PuA 提取码&#xff1a;pbli &#xff08;免费永久有效&#xff0c;免安装&#xff0c;解压后配置环境变量即可使用&#xff09; 1 下载 解压后随便放到一个地方&#xff1a; 复制“bin”路径&am…

SpringCloudAlibaba[Nacos]注册配置中心注册与发现服务

Nacos的全称是Dynamic Naming and Configuration Service&#xff0c;Na为naming/nameServer即注册中心,co为configuration即注册中心&#xff0c;service是指该注册/配置中心都是以服务为核心。是阿里巴巴开源易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 Nac…

安装vue发生异常:npm ERR! the command again as root/Administrator.

一、异常 npm ERR! The operation was rejected by your operating system. npm ERR! Its possible that the file was already in use (by a text editor or antivirus), npm ERR! or that you lack permissions to access it. npm ERR! npm ERR! If you believe this might b…

【LeetCode:910. 最小差值 II + 模拟 + 思维】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

html,css,js实现Upload 上传

实现效果&#xff1a; 代码实现&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Docum…

基于Multisim的汽车尾灯控制电路设计与仿真

假设汽车尾部左右量测各有3个指示灯&#xff08;用发光二极管模拟&#xff09;1. 汽车正常运行时指示灯全灭&#xff1b;2.右转弯时&#xff0c;右侧3个指示灯按右循环顺序点亮&#xff1b;.3. 左转弯时&#xff0c;左侧3个指示灯按左循环顺序点亮&#xff1b;4.临时刹车时所有…

【C语言刷力扣】910.最小差值 ||

题目&#xff1a; 解题思路; 由于需要对数组中的每一个进行 k 或 -k 的操作&#xff0c;这时要求最小差值&#xff0c;即对较大的数 -k 对较小的数 k。 需要先对数组进行排序&#xff0c;再枚举对元素的操作。 对 nums[0] 到 nums[i - 1] 的数进行 k对 nums[i] 到 nums[numsS…

Java笔试05

在Java中&#xff0c;final 关键字可以用于修饰类、方法和变量&#xff1a; 修饰类&#xff1a; 被 final 修饰的类不能被继承&#xff0c;即不能有子类。这通常用于工具类或者不希望被扩展的类。 修饰方法&#xff1a; 被 final 修饰的方法不能被子类覆盖。这通常用于确保类…

Yolo目标检测:实时性与准确性的完美结合

在目标检测领域&#xff0c;Yolo&#xff08;You Only Look Once&#xff09;算法无疑是一颗璀璨的明星。自2016年由Joseph Redmon等人提出以来&#xff0c;Yolo凭借其出色的实时性和准确性&#xff0c;迅速在多个应用场景中崭露头角。本文将详细介绍Yolo目标检测的基本原理、优…

Qt学习笔记第21到30讲

第21讲 new/delete关键字 new关键字 在 C 中&#xff0c; new 关键字用于动态分配内存。它是 C 中处理动态内存分配的主要工具之一&#xff0c;允许在程序运行时根据需要分配内存。 用法 ①分配单个对象&#xff1a;使用 new 可以在堆上动态分配一个对象。例如&#xf…

面向对象进阶(上)(JAVA笔记第二十二期)

p.s.这是萌新自己自学总结的笔记&#xff0c;如果想学习得更透彻的话还是请去看大佬的讲解 目录 static修饰符静态变量静态方法 工具类工具类的使用例子第一题第二题 static注意事项继承关系建立继承关系的格式继承的好处及使用场景继承的特点继承体系的设计继承中类的三大要素…