Linux - 动静态库

news2024/10/24 8:35:29

文章目录

    • 一、静态库
      • 1、定义
      • 2、文件扩展名
      • 3、生成静态库
      • 4、使用静态库
      • 5、静态库的优缺点
    • 二、动态库
      • 1、定义
      • 2、文件扩展名
      • 3、生成动态库
      • 4、使用动态库
      • 5、动态库的优缺点
      • 6、简单动态库加载
    • 三、补充


一、静态库

1、定义

静态库是在编译时链接到最终的可执行文件中的库。这意味着,在程序编译时,静态库中的代码会被复制到最终的可执行文件中。

2、文件扩展名

在Linux下静态库通常以 .a 作为文件扩展名(archive file)。

3、生成静态库

(1)ar指令
功能

用于创建、修改和提取归档文件(archive files),这些归档文件通常被称为静态库(static library)。

语法

ar [参数选项] [归档文件名] [目标文件列表]

常用选项

c:创建归档文件。
r:向归档文件中添加目标文件。如果目标文件已经存在于归档文件中,则替换它。
d:从归档文件中删除目标文件。
t:列出归档文件中包含的目标文件列表。
x:从归档文件中提取目标文件。

(2)生成静态库
mystring.h

  1 #pragma once                                                                                                                     
  2                                                                                 
  3 int my_strlen(const char * ptr); 

mystring.c

  1 #include"mystring.h"                                                                                                             
  2                                                                                 
  3 int  my_strlen(const char * ptr)                                                
  4 {                                                                               
  5     int count = 0;                                                              
  6     while(*ptr)                                                                 
  7     {                                                                           
  8         count++;                                                                
  9         ++ptr;                                                                  
 10     }                                                                           
 11                                                                                 
 12     return count;                                                               
 13 }

生成mystring.o

gcc -c mystring.c  -o mystring.o

使用mystring.o 生成静态库

ar -rc libmystring.a mystring.o //命名lib***.a

4、使用静态库

假设main.c源文件使用上述的库。

  1 #include"mystdio.h"                                                                                                              
  2 #include"mystring.h"                                                            
  3 #include<string.h>                                                              
  4 #include<stdio.h>                                                               
  5 int main()                                                                      
  6 {                                                                               
  7     const char * s = "hehe";                                                    
  8     printf("%d\n",my_strlen(s));                                                
  9     return 0;                                                                   
 10 }

(1)安装到系统路径下
将库拷贝到系统路径下

sudo cp libmystring.a /usr/lib

将头文件拷贝到系统路径下

udo cp mystring.h /usr/include

生成可执行文件
-l 选项:指定库名(去掉lib和后缀)
如果不指定库名,即便有路径也找不到库。

gcc main.c -o main -lmystring

运行生成的可执行文件
在这里插入图片描述
(2)和源文件一起
-L选项:指定库的路径。

生成可执行文件

gcc main.c -o main -L. -lmystring

运行生成的可执行文件
在这里插入图片描述
(3)使用带路径的库
在这里插入图片描述

-I选项:指定头文件的目录。

生成可执行文件

gcc main.c -o main -I./stdc/inclde -L./stdc/lib -lmystring

执行生成可执行文件
在这里插入图片描述

5、静态库的优缺点

优点:

  1. 无需额外的库文件:因为代码已经被复制到可执行文件中,所以运行时不需要额外的库文件。
  2. 部署简单:只需分发最终的可执行文件。

缺点:

  1. 增大可执行文件大小:因为每个使用静态库的程序都会包含库的副本。
  2. 浪费内存:如果多个程序使用同一个静态库,每个程序都会占用相同的代码空间。
  3. 当库文件修改时,使用当前静态库的程序可能需要重新编译。

二、动态库

1、定义

动态库(也叫共享库)是在程序运行时被链接到可执行文件中的库。这意味着,在程序运行时,动态库中的代码会被加载到内存中,并且可以被多个程序共享。

2、文件扩展名

在Linux下动态库通常以 .so(Shared Object)作为文件扩展名。

3、生成动态库

生成.o文件

gcc -c -fPIC mystring.c -o mystring.o

-fPIC 选项的作用是指示编译器生成与位置无关的代码(Position Independent Code)。这种代码可以在内存中的任何位置运行,而不需要重新定位。这对于共享库(动态库)来说是非常重要的,因为共享库在加载到进程地址空间时,其加载地址通常不是固定的,而是由操作系统动态决定的。。

生成动态库

gcc -shared -o libmystring.so mystring.o //通常以lib作为前缀

-shared 选项告诉编译器生成共享库。

4、使用动态库

(1)安装到系统路径下
将库拷贝到系统路径下

sudo cp libmystring.so  /usr/lib

将头文件拷贝到系统路径下

sudo cp mystring.h  /usr/include

生成可执行文件

gcc main.c -o main  -lmystring

运行生成可执行文件
在这里插入图片描述
(2)和源文件一起或者指定路径下
生成可执行文件
如:使用指定路径:

gcc main.c -o main  -I./stdc/include -L./stdc/lib  -lmystring

执行生成可执行文件
执行失败了,原因如下:
在这里插入图片描述
找不到动态库。
为什么编译成功了,还会报这种错误呢?
因为在编译时,指定的路径是给编译器看的,所以在编译时能找到库不会出错,而在执行时,系统链接库时会在系统默认路径下找(如/usr/lib),在库中找不到所以在执行时就会报错。

如何证明?
命令 ldd [可执行文件] ,可以看到可执行文件依赖的库
在这里插入图片描述
怎么解决?
使用软链接,让库和系统默认路径建立软连接。

sudo ln -s /home/xzy/112/dir3/stdc/lib/libmystring.so  /usr/lib/libmystring.so

在这里插入图片描述
再次运行可执行文件
在这里插入图片描述
(3)、修改环境变量
在环境变量LD_LIBRARY_PATH中加上库的路径,如果没有就创建。

添加环境变量

export LD_LIBRARY_PATH=/home/xzy/112/dir3/stdc/lib

在这里插入图片描述

5、动态库的优缺点

优点

  1. 节省磁盘和内存空间:因为多个程序可以共享同一个动态库。
  2. 便于更新和维护:只需更新动态库文件,而无需重新编译使用它的程序。
  3. 支持模块化:可以动态加载和卸载库,实现更灵活的程序设计。

缺点

  1. 部署复杂:需要确保动态库文件在运行时可用,可能需要额外的配置。
  2. 兼容性问题:不同版本的动态库可能不兼容,需要确保程序与库的版本匹配。

6、简单动态库加载

在这里插入图片描述

三、补充

(1)gcc/g++默认使用动态链接。
(2)如果同时提供动态库和静态库,那么默认使用动态库,如果想强制使用需要在编译指令后面加上-static选项。
(3)如果只提供静态库,不提供动态库,gcc/g++没得选,只能针对静态库才用局部的静态链接。

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

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

相关文章

ubuntu 22.04网线连接无ip、网络设置无有线网界面(netplan修复)

目前遇到过树莓派和其他设备安装 ubuntu22.04&#xff0c; 使用有线网络一段时间&#xff08;可能有其他软件安装导致&#xff09;造成有线网络未启动无ip分配的问题。 1、动态分配 通过命令行启动dhcpclient实现 网络eth0存在异常&#xff0c;网口灯电源和信号灯均点亮&am…

基于Fourier的两个人形机器人:从改进的3D扩散策略之iDP3到从单个RGB视频中模仿学习的OKAMI

前言 今天10.23日&#xff0c;明天1024则将作为长沙程序员代表&#xff0c;在CSDN和长沙相关部门举办的1024程序员节开幕式上发言&#xff0c;欢迎广大开发者来长工作 生活 考察 创业&#xff0c;​包括我司七月也一直在招聘大模型与机器人开发人员 后天&#xff0c;则将和相…

基于 Datawhale 开源的量化投资学习指南(7):量化择时策略

1. 引言 在量化投资中&#xff0c;择时策略是实现超额收益的关键之一。量化择时策略不同于传统的主观判断&#xff0c;它通过数学模型、技术分析以及大数据等手段&#xff0c;对市场进行客观分析&#xff0c;从而捕捉买卖时机。合理运用择时策略&#xff0c;能够帮助投资者在市…

vuex使用modules模块化

1、main.js引入 //引入vuex import store from ./store new Vue({el: #app,router,store,components: { App },template: <App/>,data:function(){return{wbWinList: [] // 定义的变量&#xff0c;全局参数}}, })2、index.js import Vue from vue; import Vuex from …

【LLM之Agent】《Tool Learning with Large Language Models: A Survey》论文阅读笔记

概述 背景信息 近年来&#xff0c;基于大型语言模型&#xff08;LLMs&#xff09;的工具学习成为增强LLMs应对复杂任务能力的有力范式。尽管这一领域快速发展&#xff0c;现有文献的碎片化以及缺乏系统组织&#xff0c;给新入门者带来了阻碍。因此&#xff0c;本论文旨在对现…

鸿蒙启航 | 搭建 HarmonyOS 开发环境来个 Hello World

2024年10月22日&#xff0c;华为公司正式发布全新一代操作系统鸿蒙Next&#xff08;HarmonyOS NEXT&#xff09;&#xff0c;此次发布标志着华为在操作系统领域的重大进展&#xff0c;成为继苹果iOS和谷歌安卓之后的全球第三大移动操作系统。以下是鸿蒙Next的一些关键特点&…

无人机加速度计算法!

一、加速度计的工作原理 内部构造&#xff1a;加速度计内部通常包含一个微小的质量块&#xff0c;该质量块通过弹簧或其他弹性元件与固定基准相连。 工作原理&#xff1a;当无人机受到加速度作用时&#xff0c;质量块会相对于固定基准产生位移。这个位移量可以通过相应的传感…

在示波器上观察到李萨如图形应如何调节

在示波器上观察李萨如图形通常用于分析两个信号之间的频率和相位关系。若要清晰地显示和调节李萨如图形&#xff0c;可以按照以下步骤进行&#xff1a; 1. 连接信号 信号源&#xff1a;将两个待测信号分别接入示波器的CH1和CH2通道。 2. 设置示波器模式为X-Y模式 在示波器菜…

【状态机DP】【记忆化搜索1:1翻译递归空间优化】力扣2771. 构造最长非递减子数组

给你两个下标从 0 开始的整数数组 nums1 和 nums2 &#xff0c;长度均为 n 。 让我们定义另一个下标从 0 开始、长度为 n 的整数数组&#xff0c;nums3 。对于范围 [0, n - 1] 的每个下标 i &#xff0c;你可以将 nums1[i] 或 nums2[i] 的值赋给 nums3[i] 。 你的任务是使用最…

LabVIEW提高开发效率技巧----离线调试

离线调试是LabVIEW开发中一项重要的技巧&#xff0c;通过使用Simulate Signal Express VI生成虚拟数据&#xff0c;开发者能够有效减少对实际硬件的依赖&#xff0c;加速开发过程。这种方法不仅可以提高开发效率&#xff0c;还能降低成本&#xff0c;增强系统的灵活性。 ​ 离…

网安加·百家讲坛 | 徐一丁:金融机构网络安全合规浅析

作者简介&#xff1a;徐一丁&#xff0c;北京小西牛等保软件有限公司解决方案部总监&#xff0c;网络安全高级顾问。2000年开始从事网络安全工作&#xff0c;主要领域为网络安全法规标准研究、金融行业安全咨询与解决方案设计、信息科技风险管理评估等。对国家网络安全法规标准…

深度学习 之 模型部署 使用Flask和PyTorch构建图像分类Web服务

引言 随着深度学习的发展&#xff0c;图像分类已成为一项基础的技术&#xff0c;被广泛应用于各种场景之中。本文将介绍如何使用Flask框架和PyTorch库来构建一个简单的图像分类Web服务。通过这个服务&#xff0c;用户可以通过HTTP POST请求上传花朵图片&#xff0c;然后由后端…

【Qt】QTableView添加下拉框过滤条件

实现通过带复选框的下拉框来为表格添加过滤条件 带复选框的下拉框 .h文件 #pragma once #include <QCheckBox> #include <QComboBox> #include <QEvent> #include <QLineEdit> #include <QListWidget>class TableComboBox : public QComboBox …

前端构建工具vite的优势

1. 极速冷启动 Vite 使用原生 ES 模块 (ESM) 在开发环境下进行工作。相比于传统构建工具需要打包所有的文件&#xff0c;Vite 只在浏览器请求模块时动态加载所需的文件。无打包冷启动&#xff1a;无需预先打包&#xff0c;项目启动非常快&#xff0c;尤其对于大型项目效果更明…

顺序表(一)(数据结构)

一. 线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列 。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串... 线性表在逻辑上是线性结构&#xff0c;是人为想象出来的数…

HCIP--1

同一区域内的OSPF路由器拥有一致的 LSDB, 在区域内&#xff0c;OSPF 采用 SPF算法计算路由一个区域太多路由器&#xff0c;硬件资源跟不上&#xff0c;所以多划分区域 OSPF 路由计算原理 1. 区域内路由计算 LSA 在OSPF中&#xff0c;每个路由器生成 LSA&#xff0c;用于告诉…

【部署篇】RabbitMq-03集群模式部署

一、准备主机 准备3台主机用于rabbitmq部署&#xff0c;文章中是在centos7上安装部署rabbitmq3.8通过文章中介绍的方式可以同样在centos8、centos9上部署&#xff0c;只需下载对应的版本进行相同的操作。 主机IP角色说明192.168.128.31种子节点192.168.128.32普通节点192.16…

Matlab学习01-矩阵

目录 一&#xff0c;矩阵的创建 1&#xff0c;直接输入法创建矩阵 2&#xff0c;利用M文件创建矩阵 3&#xff0c;利用其它文本编辑器创建矩阵 二&#xff0c;矩阵的拼接 1&#xff0c;基本拼接 1&#xff09; 水平方向的拼接 2&#xff09;垂直方向的拼接 3&#xf…

Linux系统基础-进程间通信(5)_模拟实现命名管道和共享内存

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 Linux系统基础-进程间通信(5)_模拟实现命名管道和共享内存 收录于专栏[Linux学习] 本专栏旨在分享学习Linux的一点学习笔记&#xff0c;欢迎大家在评论区交流讨…

LeetCode--删除并获得点数--动态规划

一、题目解析 二、算法原理 根据题意&#xff0c;在选择了元素 x 后&#xff0c;该元素以及所有等于 x−1 或 x1 的元素会从数组中删去。若还有多个值为 x 的元素&#xff0c;由于所有等于 x−1 或 x1 的元素已经被删除&#xff0c;我们可以直接删除 x 并获得其点数。因此若选…