Linux 动态库和静态库

文章目录

  • 前言
  • 动态库创建和使用
  • 静态库创建和使用
  • 动态库和静态库差异
    • 生成过程的差异
    • 运行效果的差异
  • 补充说明
    • 库的名称的注意事项
    • 库的搜索路径的方法
    • 什么是位置无关代码
    • 动态链接与静态链接
    • /usr/lib 和 /usr/local/lib

前言

动静态库的创建和使用部分更多的是意在说明动态库和静态库在Linux操作系统中的具体存在,在此基础之上才能解说原理,分析优缺点。

动态库创建和使用

  1. 文件结构概览
    在这里插入图片描述
  2. 文件内容展示
    main.cpp
#include "myMathA.hpp"
#include "myMathB.hpp"int main()
{int a = 10 ; int b = 5 ; printf("a=%d b=%d \n", a, b);myMathA(a,b);myMathB(a,b);return 0 ; 
}

myMathA.cpp :

#include "myMathA.hpp"
void myMathA(int x, int y)
{printf("%d\n", x + y);
}

myMathA.hpp :

#pragma once
#include <stdio.h>
void myMathA(int x, int y) ;

myMathB.cpp :

#include"myMathB.hpp"void myMathB(int x, int y)
{printf("%d\n", x - y);
}

myMathB.hpp :

#pragma once
#include <stdio.h>
void myMathB(int x, int y) ; 

makefile:

main:main.cpp g++  main.cpp -o main -L./ -lexample   # 使用动态库指令.PHNOY:test
test:  # 生成动态库指令gcc -c -fpic myMathA.cpp myMathB.cpp  gcc -shared myMathA.o myMathB.o -o libexample.so.PHNOY:clean
clean:rm -f libexample.so myMathA.o myMathB.o main`
  1. 生成动态库指令:
	gcc -c -fpic myMathA.cpp myMathB.cppgcc -shared myMathA.o myMathB.o -o libexample.so
  1. 使用动态库指令 :
g++  main.cpp -o main -L./ -lexample 
  1. 运行程序验证指令:
./main
  1. 运行结果: (linexample.so即为动态库)
    在这里插入图片描述

静态库创建和使用

  1. 文件结构概览:
初始文件结构和内容与动态库创建和使用结构相同,内容除了生成动态库指令和使用动态库指令不同,其他完全相同。
  1. 生成静态库指令
	gcc -c myMathA.cpp myMathB.cppar -rc libexample.a myMathA.o myMathB.o
  1. 生成结果 : libexampel.a 即为静态库
    在这里插入图片描述
  2. 使用动态库指令
	g++  main.cpp -o main -L./ -lexample 
  1. 运行结果: 一样

动态库和静态库差异

生成过程的差异

在这里插入图片描述

先说普通可执行文件生成过程,普通可执行文件的生成文件的顺序是:

 .c文件 —> .i文件  —>  .s文件  —> .o文件 —> 链接  —> .exe文件

动态库文件生成并使用的过程:

(声明了.c文件中函数的.h文件) + .c文件 —> .i文件  —>  .s文件  
—>(fpic指令生成的位置无关.o文件).o文件 —> (shared指令).so动态库文件 —> 
(参与其他普通可执行的链接过程)—> .exe文件  

静态库文件生成并使用的过程:

(声明了.c文件中函数的.h文件) + .c文件 —> .i文件  —>  .s文件  —> .o文件—> (ar指令生成).a静态库文件 ——> (参与其他普通可执行的链接过程) —> .exe文件  
  1. 动态链接的.o文件须是位置无关的。
  2. 在 “参与其他普通可执行的链接过程” 这一行为上,静态库直接把库中的代码整个链接到可执行文件中去,而动态库则仅仅将一个动态库的函数入口地址表编入可执行文件中去。

运行效果的差异

  1. 由于静态库是将整个库函数代码链接入可执行程序内,所以在可执行程序生成后,即使删除静态库也不会影响静态库的使用。

  2. 由于动态库只将函数入口地址表编入可执行文件中,所以在可执行程序运行开始执行前要按照指定动态库的位置找到动态库,并将动态库中的函数的内容(机器码)加载到内存中(这个操作由操作系统完成) ,故不能删除动态库,也不能移动动态库在文件系统中的位置。

  3. 由于静态库是将整个库函数代码链接入可执行程序内,所以静态库生成的可执行文件在磁盘中占用的空间相较于动态库生成的可执行文件的占用空间要大。

  4. 在运行时,只有被实际使用的动态库的代码和数据才会被加载到内存中,因此相比静态库,动态库的内存消耗可能会更小。

  5. 也 “2” 中所述现象可知,动态在运行时是被加载在内存中的,此特性结合操作系统的虚拟内存机制可以实现,多个包含了同一个动态库的可执行程序可同时使用该动态库,且只消耗一份加载该动态库的物理内存。此情况下,整体来看,相较于静态库,动态库既节省了磁盘资源又节省了物理内存资源。

  6. 由于静态库的代码和数据完整地复制到可执行文件中,因此在运行时不需要进行动态加载,可以直接执行。这样可以减少动态链接的开销,因此相较于动态库,静态库的执行效率更高。

补充说明

库的名称的注意事项

  1. 库文件的名称必须以lib开头。
  2. 使用gcc指令链接库时需要去掉库的lib开头文件后缀

库的搜索路径的方法

  1. 生成可执行文件时,用gcc -L选项指定搜索路径,如果指定了多个搜索路径,会依次搜索这些路径。
  gcc main.c -L./ -lexample
  1. 通过环境变量LD_LIBRARY_PATH搜索

可以通过设置LD_LIBRARY_PATH环境变量来指定动态库的搜索路径。该环境变量可以设置为一个或多个路径,路径之间使用冒号进行分隔。例如:

export LD_LIBRARY_PATH=/path/to/library:/another/path/to/library

追加路径的指令

export LD_LIBRARY_PATH=export LD_LIBRARY_PATH:root/example/

root/example/为追加的搜索路径

  1. 配置文件/etc/ld.so.conf和/etc/ld.so.conf.d/

可以编辑配置文件/etc/ld.so.conf,将需要搜索的动态库路径添加到其中。每行一个路径,可以使用文本编辑器打开并编辑。另外,还可以在/etc/ld.so.conf.d/目录下创建以.conf为后缀的文件,每个文件列出一个路径。编辑完成后,需要运行以下命令更新动态库缓存:

sudo ldconfig
  1. 搜索默认库路径

默认的库路径:系统会默认搜索一些常用的库路径,如/lib和/usr/lib。通常情况下,这些路径已经包含了大部分系统和常用的库文件。

动态库搜索路径的优先级是按照上述方法的顺序进行的。即先搜索LD_LIBRARY_PATH指定的路径,然后是配置文件中的路径,最后是默认的库路径。

什么是位置无关代码

位置无关代码(Position-Independent Code,PIC)是一种计算机程序代码的编译方式,它可以在内存中的任何位置执行,而不依赖于代码在内存中的具体位置。这种编译方式主要用于动态链接库(DLL)和可执行文件等需要在不同的内存地址空间中加载和执行的程序。

传统的代码编译方式会将代码中的绝对地址直接编码为指令,这样在加载到内存中时,需要进行重定位操作,将代码中的绝对地址替换为实际的内存地址。而位置无关代码则通过使用相对地址和间接寻址等技术,使得代码中的地址都是相对于某个基地址的偏移量,从而在加载时不需要进行重定位,可以直接在内存中执行。

位置无关代码的优点是可以在不同的内存地址空间中加载和执行,提高了代码的可移植性和共享性。它可以减少代码的重定位开销,简化了程序的加载过程,同时也增加了代码的安全性,防止恶意代码利用绝对地址进行攻击。

在现代操作系统和编译器中,位置无关代码已经成为一种常见的编译方式,广泛应用于动态链接库、可执行文件和操作系统内核等领域。

请注意,生成位置无关代码可能会导致一些性能损失,因为相对寻址和间接寻址可能比绝对寻址更慢。因此,在编译时需要权衡代码的可移植性和性能需求。

动态链接与静态链接

静态链接(Static Linking):
静态链接是将库文件的代码和数据复制到可执行文件中,使得可执行文件独立于外部的库文件。在静态链接中,编译器将程序所需的库文件的代码和数据直接嵌入到最终的可执行文件中。这意味着可执行文件包含了所有依赖的库函数和数据,因此它可以在没有外部库文件的情况下独立运行。静态链接的优点是可执行文件的移植性较好,但缺点是可执行文件的体积较大。

动态链接(Dynamic Linking):
动态链接是在程序运行时,通过动态链接器将程序与库文件进行连接。在动态链接中,可执行文件只包含对库函数的引用,而不包含实际的库函数代码和数据。当程序运行时,动态链接器会在系统中搜索并加载所需的库文件,并建立程序与库文件之间的链接关系。动态链接的优点是可执行文件的体积较小,多个程序可以共享同一个库文件,但缺点是程序在运行时需要依赖外部的库文件。

/usr/lib 和 /usr/local/lib

/usr/lib:这是系统级别的库路径,用于存放系统安装的共享库文件。这些库文件是由操作系统或软件包管理器安装的,供系统中的各种程序使用。通常,这些库文件是与操作系统版本和发行版相关的。

/usr/local/lib:这是本地级别的库路径,用于存放用户自己安装的共享库文件。当用户从源代码编译并安装软件时,通常会将其安装在/usr/local目录下。因此,相关的库文件也会被安装在/usr/local/lib路径下

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

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

相关文章

关于枚举的简单理解

1. 枚举的简单认识 1.1 枚举的引入 枚举是在JDK1.5以后引入的。主要用途是&#xff1a;将一组常量组织起来&#xff0c;在这之前表示一组常量通常使用定义常量的方式如下面的代码所示&#xff1a; public static final int RED 1; public static final int GREEN 2; public…

【MySQL】(DDL)总结

总结&#xff1a; 1.DDL数据库操作 show database; //查看当前创建的数据库 create database 数据库名; //创建数据库 use 数据库; //切换数据库 select database(); //查看当前所处的数据库(当前进入的那个数据库) drop database 数据库名; //删除数据库名 2.DDL表操作 …

鸿蒙开发之网络请求

//需要导入http头文件 import http from ohos.net.http//请求地址url: string http://apis.juhe.cn/simpleWeather/queryText(this.message).maxFontSize(50).minFontSize(10).fontWeight(FontWeight.Bold).onClick(() > {console.log(请求开始)let req http.createHttp()…

【音视频 | H.264】H.264视频编码及NALU详解

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

2023“楚怡杯”湖南省赛“信息安全管理与评估“--数字取证调查(高职组)

2023“楚怡杯”湖南省“信息安全管理与评估”(高职组)任务书 2023“楚怡杯”湖南省“信息安全管理与评估”(高职组)任务书第一阶段竞赛项目试题第二阶段竞赛项目试题第二部分 数字取证调查:需要环境私聊博主:2023“楚怡杯”湖南省“信息安全管理与评估”(高职组)任务书…

C语言——谁考了第k名(头歌编程刷题)

目录 一、题目描述&#xff1a; 二、输入格式&#xff1a; 三、输出格式&#xff1a; 四、输出样例&#xff1a; 五、输出样例&#xff1a; 六、代码呈现&#xff1a; 一、题目描述&#xff1a; 在一次考试中&#xff0c;每个学生的成绩都不相同&#xff0c;现知道了每个…

TCP与UDP:网络世界中的“顺丰快递”与“广播电台”

随着互联网的普及&#xff0c;我们每天都在与网络打交道。而在这背后&#xff0c;数据的传输离不开TCP和UDP这两种传输协议。它们就像网络世界中的“顺丰快递”和“广播电台”&#xff0c;各自有着不同的工作方式和特点。让我们一起来了解一下它们吧&#xff01; 一、TCP&…

如何下载 GitHub 私有仓库

概述 GitHub 是一个用于托管代码的开源平台。它提供私有仓库功能&#xff0c;允许用户将代码保密。如果您需要下载 GitHub 私有仓库&#xff0c;可以使用以下两种方式。 方式一&#xff1a;使用 SSH 密钥 SSH 密钥是一种安全的身份验证方法&#xff0c;可用于访问 GitHub 私…

了解 Flutter 3.16 功能更新

作者 / Kevin Chisholm 我们在季度 Flutter 稳定版发布会上带来了 Flutter 3.16&#xff0c;此版本包含诸多更新: Material 3 成为新的默认主题、为 Android 带来 Impeller 的预览版、允许添加适用于 DevTools 的扩展程序等等&#xff0c;以及同步推出 Flutter 休闲游戏工具包重…

浅谈基于不信任的防御性编程

背景 在实际开发过程中&#xff0c;我们经常遇到这样的场景&#xff1a; 后端报错了&#xff0c;手忙脚乱一顿排查&#xff0c;发现是前端传的参数为空&#xff0c;或者格式不对&#xff1b;后端又报错了&#xff0c;传参没问题&#xff0c;根据日志流发现&#xff0c;是某“给…

CAN 五: CAN编程实践

1、CAN基本驱动步骤 (1)CAN参数初始化 工作模式、波特率等函数&#xff1a;HAL_CAN_Init (2)使能CAN时钟和初始化相关引脚 GPIO模式设为复用功能模式函数&#xff1a;HAL_CAN_MspInit(CAN的初始化回调函数) (3)设置过滤器 过滤器的配置函数&#xff1a;HAL_CAN_ConfigFil…

Photoshop插件3D Map Generator Geo的使用记录1(版本说明、安装卸载使用和高程数据生成3D地形图的准备工作)

3D Map Generator是一款强大的地图创建和定制化工具&#xff0c;具有以下特点和功能&#xff1a; 快速创建3D地图&#xff1a;用户可以通过该工具快速创建出高质量的3D地图&#xff0c;而无需具备专业的GIS或PS技能。支持多种图层类型&#xff1a;3D Map Generator支持多种图层…

【vmware】虚拟机固定ip和网络配置

废话不多说&#xff0c;直接干货 桥接模式不多说&#xff0c;动态ip&#xff0c;一般一键下一步就可 本文主要讲 NAT模式下 静态IP设置及公网问题 创建虚拟机 查看ip ip a 或者 ifconfig 设置静态ip 1.设置虚拟机网络 点击上图中NAT设置&#xff0c;配置网关IP&#xff08;vmv…

Vue学习计划-Vue2--VueCLi(四)组件传值和自定义事件

1. 组件传值 组件化编码流程&#xff1a; 拆分静态组件&#xff1a;组件要按照功能点拆分&#xff0c;命名不要与html元素冲突实现动态组件&#xff1a;考虑好数据的存放位置&#xff0c;数据是一个组件在用&#xff0c;还是一些组件在用&#xff1a; 一个组件在用&#xff0c…

蓝桥杯专题-真题版含答案-【排序法 - 改良的选择排序】【插补搜寻法】【稀疏矩阵】【欧拉与鸡蛋】

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分…

PMP项目管理 - 质量管理

系列文章目录 现在的一切都是为将来的梦想编织翅膀&#xff0c;让梦想在现实中展翅高飞。 Now everything is for the future of dream weaving wings, let the dream fly in reality. PMP项目管理 - 质量管理 系列文章目录一、规划质量管理 - 关注工作需要达到的质量二、管理…

java stream的常见操作

1.List<String> 转 List<Integer> 如果 strList 中全是数字字符串&#xff0c;可通过如下转换为 integerList List<String> strList new ArrayList<>(Arrays.asList("7","8","9"));List<Integer> integerList …

【golang/g3n】3D游戏引擎G3N的windows安装与测试

目录 说在前面安装测试 说在前面 操作系统&#xff1a;win 11go version&#xff1a;go1.21.5 windows/amd64g3n版本&#xff1a;github.com/g3n/engine v0.2.0其他&#xff1a;找了下golang 3d相关的库&#xff0c;目前好像就这个比较活跃 安装 按照官方教程所说&#xff0c;…

当初自己为什么选择计算机?

还记得当初自己为什么选择计算机&#xff1f; 为什么当初选择计算机行业&#xff1f; 要说爱上计算机应该是高中的时候了&#xff0c;那时候第一次接触编程&#xff08;C&#xff09;&#xff0c;说实话&#xff0c;第一次写程序的时候感觉头大&#xff0c;啥都不会&#xff0c…

05 Vue中常用的指令

概述 All Vue-based directives start with a v-* prefix as a Vue-specific attribute. 所有基于 Vue 的指令都以 v-* 前缀作为 Vue 特有的属性。 v-text The v-text directive has the same reactivity as with interpolation. Interpolation with {{ }} is more perform…