Linux 库文件——静态库和共享库

news2024/12/23 17:45:57

一、库文件的概念

库是一组预先编译好的方法(.o文件)的集合。Linux系统存储的库的位置一般在:/lib 和 /usr/lib。

在 64 位的系统上有些库也可能被存储在/usr/lib64 下。库的头文件一般会被存储在/usr/include 下或其子目录下。

库有两种,一种是静态库,其命令规则为libxxx.a,一种是共享库,其命令规则为libxxx.so。

二、静态库和共享库

如果静态库和共享库同时存在,会优先选择使用共享库。

1.静态库的使用方法

直接把所要用到的静态库中方法的实现包含到一个可执行程序main中。

【例】

假如现在自己实现了两个方法add和max,这两个实现就在一个静态库文件中,假设这个库文件名为libfoo.a,然后自己写了一个程序main.c,在main.c中调用了add方法,首先要将main.c编译为main.o二进制指令文件。接下来到了链接的步骤,链接的时候,不止用到了存放自己实现的方法的库libfoo.a,把libfoo.a静态库中的方法拷贝一份用来链接。还会用到一些其他的库,其一,在执行主函数之前,我们需要执行一些代码,这些代码是直接从一些.o文件中链接过来的,在这些代码中才会调用主函数main程序,所以,我们自己要实现一个main的方法作为一个入口。其二,比如printf实现的方法所在的C库等一些标准库也需要链接。最终生成的可执行程序main就包括自己编写的.c文件和链接过来的库中的方法。

2.共享库的使用方法

只是标记共享库中使用到的方法,并不会把共享库中的方法的实现包含在一个可执行程序main中。

【例】

假如现在自己实现了两个方法add和max,这两个实现就在一个静态库文件中,假设这个库文件名为libfoo.so,然后自己写了一个程序main.c,在main.c中调用了add方法,首先要将main.c编译为main.o二进制指令文件。接下来到了链接的步骤,链接的时候,其一,在主函数执行之前会执行一部分代码,这些代码从一些.o文件中链接过来,其二,我们会把像C库这样的标准库链接过来,其三,标记用到共享库中的add方法。

现在有一个简单的main程序:

在这里插入图片描述

查看这个main程序的共享库,发现C库会默认链接,libc.so就是C库:

在这里插入图片描述

3.静态库和共享库的优缺点

(1)静态库

优点:
把所用到的库中的方法的实现都包含到自己的可执行程序中,它已经成为可执行程序的一部分了,运行的时候也不会去寻找所用到的库,把这个库删掉也没有影响。把所用到的库都包含到自己的可执行程序中,无论这个环境中有没有相应的库程序都可以执行。

缺点:
①所占内存大;
②库的更新不方便,在更新库的时候必须得重新编译程序。

(2)共享库

优点:
①所占内存小;
②库的更新非常方便,直接用新库覆盖旧库就可以了

缺点:
没有包含,要在运行的时候去寻找所要用到的库,要动态链接相应的库,所以在这个执行该程序的计算机上必须存在需要用到的所有共享库,一旦相应的库不存在,程序就无法运行。

三、静态库的生成和使用

头文件都在/usr/include

库文件都在/usr/lib或者/lib

可执行程序都在/usr/bin或者/bin

1.生成一个静态库的步骤:

示例:目前有一个add.c和max.c文件,add.c和max.c都被声明在一个头文件foo.h中:

在这里插入图片描述

(1)第一步,将所有的.c文件编译为.o文件:

在这里插入图片描述

(2)第二步,把.o文件打包到一个库中,使用ar命令将第一步编译的所有”.o”文件生成静态库

以下把add.o max.o文件生成了一个静态库libfoo.a

在这里插入图片描述

对于ar crv libfoo.a add.o max.o中的

ar是一个命令

crv中的:
c是创建库
r是将方法添加到库中
v显示过程

libfoo.a是所创建的库名

add.o max.o是将要打包到库中的.o文件

2.静态库的使用

(1)先建立一个目录liba

把头文件foo.h和静态库libfoo.a都拷贝到该目录下:

在这里插入图片描述

(2)创建一个main.c文件,写测试代码

在这里插入图片描述
在这里插入图片描述

(3)生成可执行文件并运行

①直接编译main.c文件(失败)

在这里插入图片描述

原因:该目录下没有add方法的实现。

②生成main.o文件后再编译main.c文件(失败)

在这里插入图片描述

失败原因:在gcc -o main main.o链接时找不到add方法

③链接的时候指定静态库生成可执行文件(成功)

在这里插入图片描述

④直接通过main.c和静态库生成可执行文件(成功)

在这里插入图片描述
编译语句gcc -o main main.c -L -lfoo中的

-L:指定库的存储路径
-l:指定库的名称(不需要前面的‘lib’和扩展名‘.a’)。

如果库在标准库中,那么在编译时就不需要指定该库的路径。

(4)删除静态库libfoo.a之后,可执行文件main仍然可以运行

在这里插入图片描述

四、共享库的生成和使用

1.共享库的生成

1.生成一个共享库的步骤:

示例:目前有一个add.c和max.c文件,add.c和max.c都被声明在一个头文件foo.h中:

在这里插入图片描述

(1)第一步,将所有的.c文件编译为.o文件

在这里插入图片描述

(2)第二步,把.o文件打包到一个库中,使用gcc命令将第一步编译的所有".o"文件生成共享库

在这里插入图片描述
生成共享库的命令gcc -shared -fPIC -o libfoo.so add.o max.o中的:

gcc代表命令
-shared代表生成的是共享库
-fPIC代表代码位置无关
-o表示输出
libfoo.so是生成的共享库的名称
add.o max.o是将要打包到库中的.o文件

2.共享库的使用

(1)先建立一个目录liba

把共享库libfoo.so和头文件foo.h都移到liba中:

在这里插入图片描述

(2)创建一个main.c文件,写测试代码

在这里插入图片描述
在这里插入图片描述

(3)生成可执行文件

①直接编译生成可执行文件(失败)

在这里插入图片描述

失败原因:找不到add方法的实现,main.c中没有add方法的实现

②使用共享库“libfoo.so”和“main.c”生成可执行文件(成功)

在这里插入图片描述

在编译语句gcc -o main main.c -L. -lfoo中:

-L:指定库的存储路径
-l:指定库的名称(不需要前面的‘lib’和扩展名‘.so’)

如果在库的存储路径有同名的共享库和静态库,gcc默认使用共享库。

(4)运行(失败)

在这里插入图片描述

失败原因分析:

首先,查看main程序用到了那些库:

在这里插入图片描述

发现libfoo.so没有找到,这是因为在运行的时候寻找库的时候只会去标准目录中寻找,gcc -o main main.c -L. -lfoo中指定的路径是告诉gcc在编译的时候去这个路径寻找需要的库。

解决办法:

①通过一些环境变量来指定main程序在加载库的时候在当前的目录下去寻找所需要的库

先设置变量”LD_LIBRARY_PATH”为当前路径,此时仍然会运行失败:

在这里插入图片描述
然后将变量”LD_LIBRARY_PATH”设置为环境变量就可以运行成功:

在这里插入图片描述

②把所需要用到的库放到标准目录下(管理员模式下操作)

在这里插入图片描述

【注意】如果把动态库移到标准目录下,并且设置了环境变量,那么会优先选择环境变量来找到库的位置。

这时候发现libfoo.so被找到了,此时就可以运行main程序了:

在这里插入图片描述

(5)删除共享库libfoo.b之后,可执行文件main就不可以运行了

在这里插入图片描述

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

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

相关文章

一个Demo搞定前后端大文件分片上传、断点续传、秒传

原文链接:https://juejin.cn/post/7266265543412351030 前言 文件上传在项目开发中再常见不过了,大多项目都会涉及到图片、音频、视频、文件的上传,通常简单的一个Form表单就可以上传小文件了,但是遇到大文件时比如1GB以上&…

Leetcode-每日一题【剑指 Offer 28. 对称的二叉树】

题目 请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。 例如,二叉树 [1,2,2,3,4,4,3] 是对称的。 1 / \ 2 2 / \ / \ 3 4 4 3 但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称…

利用三维内容编辑器制作VR交互课件,简单好用易上手

随着虚拟现实技术的不断发展,越来越多的教育机构开始尝试将其应用于教育教学中。然而,要实现这一目标并不容易,需要专业的技术支持和开发团队。 为了解决这一问题,广州华锐互动研发了三维内容编辑器,它是一种基于虚拟现…

13.3 目标检测和边界框

锚框的计算公式 假设原图的高为H,宽为W 详细公式推导 以同一个像素点为锚框,可以生成 (n个缩放 m个宽高比 -1 )个锚框 给训练集标注锚框 每个锚框包含的信息有:每个锚框的类别 和 偏移量。 偏移量指的是:真实边界相对于锚框的偏移量。 …

Android系统-ServiceManager1

目录 引言 概念 启动 流程图 main binder_open binder_become_context_manager binder_ioctl binder_ioctl_set_ctx_mgr binder_new_node binder_loop binder_write binder_ioctl binder_ioctl_write_read binder_thread_write binder_parse bio_init bio_in…

新鲜出炉的小工具,将Claude 100K转化为免费可用的OpenAI API

上个月转载了一篇文章,讲的就是刚刚发布的Claude 2.0,可以说是非常强大了:ChatGPT最强竞品Claude2来了:代码、GRE成绩超越GPT-4,免费可用 但是可惜的是,Claude虽然免费使用,但是不开放API给我们…

【uni-app】 .sync修饰符与$emit(update:xxx)实现数据双向绑定

最近在看uni-app文档,看到.sync修饰符的时候,觉得很有必要记录一下 其实uni-app是一个基于Vue.js和微信小程序开发框架的跨平台开发工具 所以经常会听到这样的说法,只要你会vue,uni-app就不难上手 在看文档的过程中,发…

邵阳人自己的民国风情街终于来了!随手一拍即是大片!

在邵阳这座美丽的城市,拥有许多非常有意思并且值得打卡的游玩景区,“丹霞之魂,国之瑰宝”的崀山、“南方呼伦贝尔”之称的高山苔地草原、被联合国誉为“神奇绿洲”的遂宁黄桑等等都是成都这座城市的代表,但在邵阳最有民国风情韵味…

【小吉带你学Git】讲解GitHub操作,码云操作,GitLab操作

🎊专栏【Git】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【如愿】 🌺欢迎并且感谢大家指出小吉的问题🥰 文章目录 🍔GitHub操作⭐安装GitHub插件⭐在idea中设置GitHub账号&…

完成图像反差处理

bmp图像的前54字节为图像头,第19个字节开始4字节为图像宽,第23字节开始4字节为图像高,图像大小为:972*720*3542099574,为宽*高*像素点头,如下: 图像的反差处理

最强自动化测试框架Playwright(10)- 截图

截图 捕获屏幕截图并将其保存到文件中: page.screenshot(path"screenshot.png")可将页面截图保存为screen.png import osfrom playwright.sync_api import Playwright, expect, sync_playwrightdef run(playwright: Playwright) -> None:browser p…

python之matplotlib入门初体验:使用Matplotlib进行简单的图形绘制

目录 绘制简单的折线图1.1 修改标签文字和线条粗细1.2 校正图形1.3 使用内置样式1.4 使用scatter()绘制散点图并设置样式1.5 使用scatter()绘制一系列点1.6 python循环自动计算数据1.7 自定义颜色1.8 使用颜色映射1.9 自动保存图表练习题 绘制简单的折线图 绘制一个简单折线图…

Playable 动画系统

Playable 基本用法 Playable意思是可播放的,可运行的。Playable整体是树形结构,PlayableGraph相当于一个容器,所有元素都被包含在里面,图中的每个节点都是Playable,叶子节点的Playable包裹原始数据,相当于输…

c++ cpp cmake opencv 深度学习模型 推理 前向部署 代码示例示意

参考实现&#xff1a; https://github.com/spmallick/learnopencv/tree/master/AgeGender 文件结构&#xff1a; 具体实现&#xff1a; #include <opencv2/imgproc.hpp> #include <opencv2/highgui.hpp> #include <opencv2/dnn.hpp> #include <tuple&g…

机器学习深度学习——seq2seq实现机器翻译(数据集处理)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——从编码器-解码器架构到seq2seq&#xff08;机器翻译&#xff09; &#x1f4da;订阅专栏&#xff1a;机…

[数据集][目标检测]道路坑洼目标检测数据集VOC格式1510张2类别

数据集格式&#xff1a;Pascal VOC格式(不包含分割路径的txt文件和yolo格式的txt文件&#xff0c;仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数)&#xff1a;1510 标注数量(xml文件个数)&#xff1a;1510 标注类别数&#xff1a;2 标注类别名称:["keng","…

指针进阶大冒险:解锁C语言中的奇妙世界!

目录 引言 第一阶段&#xff1a;&#x1f50d; 独特的字符指针 什么是字符指针&#xff1f; 字符指针的用途 演示&#xff1a;使用字符指针拷贝字符串 字符指针与字符串常量 小试牛刀 第二阶段&#xff1a;&#x1f3af; 玩转指针数组 指针数组是什么&#xff1f; 指针…

操作系统—网络系统

什么是零拷贝 磁盘是计算机系统最慢的的硬件之一&#xff0c;所以有不少优化磁盘的方法&#xff0c;比如零拷贝、直接IO、异步IO等等&#xff0c;这些优化的目的是为了提高系统的吞吐量&#xff0c;另外操作系统内核中的磁盘高度缓存区&#xff0c;可以有效的减少磁盘的访问次…

HCIP---重发布技术

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 前文通过学习OSPF的不规则区域&#xff0c;了解了如何对不规则区域使用OSPF获取路由&…

JavaWeb-Servlet服务连接器(二)

目录 Request&#xff08;获取请求信息&#xff09; 1.获取请求行内容 2.解决乱码问题 3.获取请求头部分 4.获取请求体 5.其他功能 Request&#xff08;获取请求信息&#xff09; 工作流程&#xff1a; 1.通过请求的url的资源路径&#xff0c;tomcat会生成相应的Servlet实…