Linux动静态库

news2024/11/27 13:29:22

目录

一、库的概念与类型

二、库的组成文件(.o)

2.1 初始源代码(.c .h)

2.2 可重定位二进制文件(.o) 

2.3 库文件(lib) 与 头文件(.h)

三、实现静态库(.a)

3.1 建立静态库文件

3.2 交付库

3.3 编译器在编译链接中的作用

3.4 使用第三方静态库与头文件

3.4.2 只指定头文件路径(×)

3.4.3 指定头路径与库文件路径(×)

3.4.4 指定头文件路径和库文件名称(√)

3.5 C编译器默认动态链接

3.6 安装第三方静态库与头文件

四、实现简单的动态库

4.1 动态库建立打包

4.2 动态链接需要给OS提供库的路径

4.3 OS找到动态库方法

4.3.1 环境变量法(临时法)

4.3.2 配置文件法

4.3.3 建立软链接(或者直接添加到系统默认路径下)

五、动静态库加载理解

5.1 静态库加载理解

5.2 动态库加载理解 


一、库的概念与类型

(百度)

库是程序代码的集合,是共享程序代码的一种方式。根据源代码的公开情况,库可以分为两种类型:

1. 开源库,公开源代码,能看到具体实现,比如:SDWebImage、AFNetworking。

2. 闭源库不公开源代码,是经过编译后的二进制文件看不到具体实现。闭源库主要分为:静态库和动态库。

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

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

二、库的组成文件(.o)

2.1 初始源代码(.c .h)

//add.h 
#pragma
#include<stdio.h>

extern int add(int a ,int b);

//sub.h
#pragma
#include<stdio.h>
extern int sub(int a,int b);


//sub.c
#include"add.h"

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

//add.c
#include"sub.h"

int sub(int a ,int b)
{
    return a - b;
}

//main.c
#include"add.h"
#include"sub.h"

int main()
{
    int a=9,b=1;
    printf("%d+%d=%d\n",a,b,add(a,b));
    printf("%d-%d=%d\n",a,b,sub(a,b));
    return 0;
}

2.2 可重定位二进制文件(.o) 

 这种文件将我们.c源代码变成了二进制文件,它依然可以链接形成exe文件,但是它们本身是二进制文件,所以没有暴漏了原来.c的源代码!我们可以将这些.o文件打包Output,用户拿着这些文件链接形成exe文件!


2.3 库文件(lib) 与 头文件(.h)

将我们.o文件集合打包成一个文件,这种文件我们称为库文件(lib)!

系统默认头文件路径 /usr/include/
默认库文件路径 /usr/lib64/

交付库--》将.a/.so 文件以及其对应的.h文件交给用户!

三、实现静态库(.a)

3.1 建立静态库文件

//makefile

//静态库.a
libmymath.a:add.o sub.o
	ar -rc $@ $^    //ar -rc 打包.o文件-》静态库(.a)
add.o:add.c
	gcc -c $^ -o $@
sub.o:sub.c
	gcc -c $^ -o $@
.PHONY:clean
clean:
	rm -f *.o

3.2 交付库

3.2.1 发布库

libmymath.a:add.o sub.o
	ar -rc $@ $^		
add.o:add.c
	gcc -c $^ -o $@
sub.o:sub.c
	gcc -c $^ -o $@

//发布
.PHONY:output
output:
	mkdir -p mylib/include    //当前路径下建立头文件目录
	mkdir -p mylib/lib       //当前路径下建立库文件目录
	cp *.h   mylib/include   //头文件打包
	cp *.a   mylib/lib       //库文件打包

.PHONY:clean
clean:
	rm -f *.o

3.2.2 用户下载库


  3.3 编译器在编译链接中的作用

编译器会在编译链接中查找库与头文件!

系统库与头文件下:

编译器如何寻找头文件?

我们在写代码的时候包含头文件,编译器会拿着这些头文件名称到系统指定路径(/usr/include/)路径下寻找!

编译器如何寻找库文件?

同样,编译器会到指定路径去寻找库!用户没有直接提供库名称,但是编译器会知道找哪些库!

编译器默认链接方式:动态库链接!

3.4 使用第三方静态库与头文件

3.4.1 单纯使用gcc -o (×)


3.4.2 只指定头文件路径(×)


3.4.3 指定头路径与库文件路径(×)


 3.4.4 指定头文件路径和库文件名称(√)

库的名称是去掉前缀(lib)和后缀的(.a/.so)剩下的!


3.5 C编译器默认动态链接


一个程序可以链接很多库文件,如果既可以链接动态库又可以链接动态库,则编译器默认选择链接动态库!除非只有一种库形式存在,否则链接方式由编译器决定!


3.6 安装第三方静态库与头文件

将第三方库文件与头文件拷贝至我们的对应的系统默认路径下:

系统默认头文件路径 /usr/include/
默认库文件路径 /usr/lib64/

这样我们就可以不带路径找到头与库文件,但是我们必须还要指定链接的库文件名称!


四、实现简单的动态库

4.1 动态库建立打包


4.2 动态链接需要给OS提供库的路径

 同样的操作,动态链接这样依旧不能运行!发现我们依旧打不开库文件!编译链接可以成功但是运行不行!编译链接时编译器的工作,我们把路径和库文件名告诉了编译器,所以可以编译链接成功!但是运行归OS管,OS找不到第三方库!OS只会在系统默认库路径下或者当前路径下查找!所以我们必须将我们的库文件安装到默认路径下!

4.3 OS找到动态库方法

4.3.1 环境变量法(临时法)

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库文件路径!

4.3.2 配置文件法

cd /etc/ld.so.conf.d/ 系统目录,查看配置文件

创建.conf类型的目录并将动态库路径添加到这个目录下! 
sudo ldconfig 更新缓存刷新一下

4.3.3 建立软链接(或者直接添加到系统默认路径下)

OS只会在系统默认库路径下或者当前路径下查找,所以我们可以:

1.在当前路径下建立库文件的软链接

2.在系统库路径下添加库文件的软链接



五、动静态库加载理解

5.1 静态库加载理解

静态链接是将静态库代码拷贝到进程的代码区,这些代码在代码区被编址!这样相当于这部分拷贝代码本身就属于我们这个进程!


5.2 动态库加载理解 


动态库链接,当我们进程代码用到了外部库函数调用/变量,OS会将其对应的动态库加载到内存中,虚拟地址空间共享区与之映射! 

外部库加载到内存后,进程如何准确找到外部库对应的函数?

进程中的外部库函数代码本身存载了自己在库中的地址偏移量!通过相对共享区起始位置的偏移量在共享区中找到自己的虚拟地址,然后映射到物理内存中找到我们函数的定义!

5.3 两者对比


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

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

相关文章

JavaScript的引入方式和基础语法~

JavaScript简介&#xff1a; JavaScript是一门跨平台&#xff0c;面向对象的脚本语言&#xff0c;来控制网页行为的&#xff0c;它能使网页可交互 W3C标准&#xff1a;网页主要由三部分组成 结构&#xff1a;HTML 表现&#xff1a;CSS 行为&#xff1a;JavaScriptJavaScript…

大数据技术架构(组件)8——Hive:Function Cases UDF/UDTF/UDAF 1

1.3、Function Cases1.3.1、窗口函数row_number&#xff1a;使用频率 ★★★★★rank &#xff1a;使用频率 ★★★★dense_rank&#xff1a;使用频率 ★★★★rank/dense_rank/row_number对比first_value&#xff1a;使用频率 ★★★last_value&#xff1a;使用频率 ★lead&am…

下班前几分钟,我彻底弄懂了并查集

目录一、并查集的由来二、代表元法2.1 初始化2.2 查询2.3 合并2.4 设计理念三、并查集的应用3.1 合并集合3.2 连通块中点的数量3.3 亲戚3.4 省份数量References一、并查集的由来 考虑这样一个场景。 现有 nnn 个元素&#xff0c;编号分别为 1,2,⋯,n1,2,\cdots,n1,2,⋯,n&…

【JVM】详解直接内存

文章目录1. 直接内存概述2. 直接内存的使用2.1 Java缓冲区2.2 直接内存3. 直接内存的释放3.1 直接内存释放原理4. 禁用显式回收对直接内存的影响1. 直接内存概述 下面是 《深入理解 Java 虚拟机 第三版》2.2.7 小节 关于 Java 直接内存的描述。 直接内存&#xff08;Direct Me…

从零开始的数模(七)层次分析法

一、概念 1.1定义 应用场景&#xff1a; 1、最佳方案选取 2、评价类问题 3、指标体系的优选 步骤&#xff1a; 1、建立层次结构模型&#xff1b; 2、构造判断(成对比较)矩阵&#xff1b; 3、层次单排序及其一致性检验&#xff1b; 4、层次总排序及其一致性检验&#xff1b; …

Mybatis 分页插件使用

1、分页插件的使用步骤 需求分析&#xff1a; 我们在前端界面获取用户表的时候&#xff0c;在界面上一次显示出成百上千条数据&#xff0c;用户体验&#xff0c;软件性能都会很糟糕&#xff0c;假设数据库内存储十万条记录&#xff0c;后端一次性返回这么多数据&#xff0c;前…

C语言深度解剖-关键字(2)

目录 1.关键字 static 源文件与头文件 static修饰全局变量 static修饰局部变量 写在最后&#xff1a; 1.关键字 static 源文件与头文件 平时我们在练习的时候&#xff0c;都只会开一个用来测试的源文件&#xff0c; 但是&#xff0c;当我们在写一个项目的时候&#xff…

Hal GPIO控制--LED/Delay实现

环境配置在CubeMx Pinout view 中点击可以设置管脚模式 &#xff0c;右击 可以配置管脚名称这里以点PB8灯为例&#xff0c;可以设置灯输出电平 &#xff0c;模式为输出&#xff0c;不进行上下拉&#xff0c; 速度 模式设置以及用户自定义名称。。时钟树配置&#xff0c;使用HSI…

FreeRTOS源码获取-->FreeRTOS移植-->FreeRTOS源码文件了解 | FreeRTOS二

目录 说明&#xff1a; 一、获取源码 1.1、FreeRTOS官网获取 1.2、正点原子开发板A盘资料\6&#xff0c;软件资料\13&#xff0c;版本-->V10.4.6 二、移植源码 2.1、移植步骤 2.1.1、添加源码、头文件路径 2.1.2、添加FreeRTOSConfig.h文件路径 2.1.3、添加或修改相…

VisualSVN Server Enterprise 5.1.1 Crack

VisualSVN Server 提供以下主要功能。 Active Directory 单点登录 允许用户使用他们当前的 Active Directory 域凭据访问 VisualSVN Server。使用安全 Kerberos V5 或 NTLM 身份验证协议。支持双因素身份验证和智能卡。 多站点存储库复制 使用 VisualSVN 分布式文件系统 (VDF…

MySQL基础(1)—— 卸载与安装

文章目录MySQL卸载【windows】1、停止MySQL服务2、软件的卸载2.1 通过控制面板卸载软件2.2 通过360软件管家等第三方软件进行删除2.3 通过MySQL安装包提供的卸载功能卸载3、残余文件的清理4、清理注册表5、删除环境变量配置MySQL安装【windows】1、下载安装包2、安装3、配置环境…

Sharding-JDBC(六)5.1.0版本,实现按月分表、自动建表、自动刷新节点

目录1.Maven 依赖2.创建表结构3.yml 配置4.TimeShardingAlgorithm.java 分片算法类5.ShardingAlgorithmTool.java 分片工具类6.ShardingTablesLoadRunner.java 初始化缓存类7.SpringUtil.java Spring工具类8.源码测试9.测试结果10.代码地址背景&#xff1a; 项目用户数据库表量…

vscode运行C/C++程序

一、vsocde对C/C的支持 Visual Studio Code对C/C语言的支持由Microsoft C/C扩展程序提供。它使得C/C在Windows、Linux和macOS等跨平台开发成为可能。 二、安装扩展程序 打开VS Code软件选择任务栏上的扩展视图图标&#xff08;下图红色方框&#xff09;或使用快捷键(CtrlShif…

【自然语言处理】情感分析(四):基于 Tokenizer 和 Word2Vec 的 CNN 实现

情感分析&#xff08;四&#xff09;&#xff1a;基于 Tokenizer 和 Word2Vec 的 CNN 实现本文是 情感分析 系列的第 444 篇&#xff0c;前三篇分别是&#xff1a; 【自然语言处理】情感分析&#xff08;一&#xff09;&#xff1a;基于 NLTK 的 Naive Bayes 实现【自然语言处…

服务发现Discovery和Eureka自我保护机制

目录 一、服务发现Discovery ​二、Eureka自我保护 &#xff08;一&#xff09;故障现象 &#xff08;二&#xff09;导致原因 &#xff08;三&#xff09;怎么禁止自我保护 三、Eureka2.0的停更 一、服务发现Discovery 对于注册进eureka里面的微服务&#xff0c;可以通…

外挂、破解软件理论与实战

外挂、破解软件理论与实战 1 理论 1.1 不同操作系统下的可执行文件 Windows【PE】 PE 格式&#xff0c;可移植可执行格式&#xff08;Portable Executable&#xff09;&#xff0c; 是 Windows 下的主要可执行文件格式。别被名字迷惑了&#xff0c;PE 文件必须是 Windows 下…

第四十六章 动态规划——状态机模型

第四十六章 动态规划——状态机模型一、通俗理解状态机DP1、什么是状态机2、什么是状态机DP二、例题1、AcWing 1049. 大盗阿福&#xff08;1&#xff09;问题&#xff08;2&#xff09;分析a.状态定义b.状态转移c.循环设计d.初末状态&#xff08;3&#xff09;代码2、AcWing 10…

C++学习/温习:新型源码学编程(三)

写在前面(祝各位新春大吉&#xff01;兔年如意&#xff01;) 【本文持续更新中】面向初学者撰写专栏&#xff0c;个人原创的学习C/C笔记&#xff08;干货&#xff09;所作源代码输出内容为中文&#xff0c;便于理解如有错误之处请各位读者指正请读者评论回复、参与投票&#xf…

01 课程简介、HTML标签【尚硅谷JavaWeb教程】

1. 课程体系设计 2. HTML标签 服务器—浏览器&#xff08;字符串"" &#xff09; demo01.html 1&#xff09;html语言是解释型语言&#xff0c;不是编译型 浏览器是容错的 2&#xff09;html页面中由一对标签组成&#xff1a; < html>称为 开始标签 < /htm…

Java基础语法——数组概念、数组内存图解(一个数组、二个数组)及二元数组的应用

目录 数组概述 数组定义格式 数组概念 数组的定义格式 数组的初始化 数组初始化概述 数组的初始化方式 Java中的内存分配 Java中一个数组的内存图解 Java中二个数组的内存图解 两个数组指向同一个地址的内存图解 数组操作中两个常见的小问题 二维数组 二维数组概述…