动态库和静态库的理解 Linux

其实库文件里面的内容就是函数的实现方法,向我们包含的头文件其实就是函数的生命,而我们编译链接程序时会自动加载库文件,最终形成可执行程序。其实我们在编译链接时不仅仅会将文件的库文件加载进来,其实头文件也是需要加载进来的,只不过也是自动加载的。

静态库

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

模拟实现静态库

其实库文件的形式都是.c文件编译成的.o目标二进制文件,然后全部打包给我们用户进行使用。如果我们用户的main函数中使用了对应库文件的函数方法,那么我们用户可以将main函数编译成.o文件,再将所有.o文件链接起来形成可执行程序即可实现。

现在我们开始模拟实现库文件,首先就是实现函数生成.o文件,所以此时的指令就是gcc -c test.c -o test.o,其实后面不接-o也是没问题的,会自动生成同名的.o文件,所以此时就十分轻松。

此时拿一个add函数和sub函数举例,实现函数声明定义分离的形式:

"add.h"

#pragma once
#include<stdio.h>
int add(int ,int);

"sub.h"

#pragma once 
#include<stdio.h>
int sub(int,int);

"add.c"

#include"add.h"
int add(int x,int y)
{
    return x+y;
}

"sub.c"

#include"sub.h"
int sub(int x,int y)
{
    return x-y;
}

"main.c"

#include"add.h"
#include"sub.h"
int main()
{
    printf("%d+%d=%d\n",3,4,add(3,4));
    printf("%d-%d=%d\n",3,4,sub(3,4));

    return 0;
}


生成.o文件和.exe的makefile:(#是注释)

test.exe:test.o add.o sub.o
	gcc -o $@ $^

%.o:%.c  # %类似于通配符,会查找当前目录下的所有后缀为.c的文件,并且会生成相同文件名的.o文件
	gcc -c $< # $<相当于一个个的.c文件各自拿过来编译

.PHONY:clean
clean:
	rm -f test.exe

 

 而生成静态库的指令就是:ar -rc  xxx.a xx.o x.o  其中rc表示(replace and create)

生成库文件的makefile:

libmymath.a:*.o
	ar -rc $@ $^  #生成静态库
.PHONY:clean
clean:
	rm -f *.a

最后就是将库文件和我们的main.c文件链接生成可执行程序了。

链接生成可执行程序:

gcc main.c -I ./ -l mymath -L ./
-I 指定头文件路径(当前路径的话会默认查找)
-L 指定库路径
-l 指定库名

首先我们要了解一下后面的指令参数,-l和-L,而我们在没有链接我们实现的静态库时,而是gcc编译器会自动的链接C语言的库,所以就不需要这两个指令参数。在此我们要知道我们写的库叫做第三方库,所以在形成可执行程序的时候需要链接我们的第三方库,而且一般还要指明路径。并且我们链接的库名称是需要去掉前缀lib和后缀.a的。

默认搜索库和头文件: 

在Linux中我们进行编译C语言文件的时候系统默认会在/usr/include中搜索头文件的,而在库文件都是在/lib64里搜索的。所以我们也可以将我们自己的的头文件和库文件拷贝到对应的路径下,那么在之后编译链接时就会直接默认像路径中寻找对应库文件链接生成可执行程序。

 

动态库

动态库是一种在运行时被可执行文件引用的库文件。它是独立于可执行文件的外部文件,可以被多个程序共享使用。动态库的文件扩展名一般为.so(在Windows下为.dll)。动态库的主要特点是在程序运行时动态加载,可以节省系统内存,同时也方便了库的更新和维护。

动态库模拟实现

其实和静态库的操作是没啥区别的,只不过有些指令的参数不同。首先还是生成.o文件,然后再将.o文件生成动态库。

makefile的实现:

libmymath.so:add.o sub.o
	gcc -shared -o $@ $^ # 生成共享库格式
%.o:%.c
	gcc -fPIC -c $< # 产生位置无关码,也就是相对编址的方式

.PHONY:output # 发行
output:
	mkdir -p mymath/include
	mkdir -p mymath/lib 
	cp -f *.h mymath/include
	cp -f *.so mymath/lib 

.PHONY:clean
clean:
	rm -rf *.o *.so mymath

 将发行的文件mymath拷贝到一个新的目录文件下:

 

链接生成可执行程序:

gcc main.c -l mymath -L mymath/lib -I mymath/include
-l :指定库名称(去掉前缀lib和后缀.so)
-L :库的所在路径
-I :头文件所在路径

 运行可执行程序:

但是我们其实还是无法直接进行运行的。

ldd指令查看所需动态库: 

 因为对于静态库来说静态库会被整个复制到可执行文件中,所以一旦编译成功了之后就和静态库没什么关系了,可执行程序也就可以直接运行,所以运行期间也不需要查找静态库而对于动态库就不一样了,动态库和可执行程序是分离的,也就是两个不同的文件,所以在运行我们可执行程序的时候就要将我们的程序和动态库都加载到内存中才可以运行起来

动态库运行时的解决方法

  1. 直接将我们的第三方动态库安装(拷贝)到系统默认的动态库/lib64目录下。也可以顺带将头文件拷贝到/usr/include下,那么我们在下次gcc编译的时候就只需要带上链接动态库的文件名就行了。
  2. 将库文件拷贝到与main.c文件在同一个目录路径下(因为动态链接时,运行可执行程序时不仅仅会在/lib64查找库文件,也会默认在当前目录下查找库文件)其实也可以通过创建软硬链接的方式进行:(软硬链接后的名称一定要与所需动态库同名
  3. 直接更改系统中关于动态库的配置文件(系统中配置文件的位置在/exc/ld.so.conf.d/中,所以我们需要在该路径下touch一个文件,然后我们vim文件,直接将我们的动态库绝对路径写入文件中即可,最后ldconfig命令刷新一下就可以。而且该配置文件内容始终有效)
  4. 将我们实现的库拷贝到环境变量LD_LIBRARY_PATH中(因为我们执行可执行程序时,系统除了会在默认路径下帮我们加载库文件外,还会在该环境变量中搜索对应的动静态库。但是只是在内存中写入,所以下次使用就不存在了)
    export LD_LIBRARY_PATH = $LD_LIBRARY_PATH : (我们库所在的路径)

我们在链接动态库的程序在运行期间也是需要库文件的,其实本质就是在编译期间会形成符号表,记录函数名与函数在库里的地址映射关系,而最后运行期间加载到内存的时候,如果主函数调用了动态库中的函数时,就会找到函数地址,但是此时需要将库文件也一同运行到内存中,这样才可以找到需要调用的函数。

 

gcc默认都是链接动态库 :

如果我们同一个库的目录文件下提供了动静态两种库,那么在gcc编译时会默认使用动态库,除非后面带上 -static选项才会使用我们的静态库。 

gcc main.c -l mymath -L mymath/lib -I mymath/include  //默认动态链接
gcc main.c -l mymath -L mymath/lib -I mymath/include -static //强制静态链接该库

 

 使用外部库

  1. 安装库。可以通过yum install -y等指令进行安装外部第三方库。
  2. 将头文件和库文件分别安装到对应的默认加载路径里。如果yum自动安装了的话就不用了
  3. gcc编译。不要忘记加上 "-l 库名"

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++输入输出流

输入/输出流类&#xff1a;iostream---------i input&#xff08;输入&#xff09; o output&#xff08;输出&#xff09; stream&#xff1a;流 iostream&#xff1a; istream类&#xff1a;输入流类-------------cin&#xff1a;输入流类的对象 ostre…

企业级大数据安全架构(六)数据授权和审计管理

作者&#xff1a;楼高 本节详细介绍企业级大数据架构中的第六部分&#xff0c;数据授权和审计管理 1.Ranger简介 Apache Ranger是一款被设计成全面掌管Hadoop生态系统的数据安全管理框架&#xff0c;为Hadoop生态系统众多组件提供一个统一的数据授权和管理界面&#xff0c; 管…

品牌突围|内容营销「共创公式」全面讲解

为什么品牌要扎根小红书&#xff1f;除了种草投放&#xff0c;品牌还能做些什么&#xff1f; 在小红书&#xff0c;迎接消费者共创的时代&#xff0c;激活品牌营销的无限潜能。 拥抱多元 在新机遇中预见未来 2023年&#xff0c;各大社交媒体平台涌现出了许多热点&#xff0c…

软件测试工作中需要使用的工具

作为一个测试人员在日常工作中会使用到很多的工具&#xff0c;今天给大家分享一下这些工具。对软件测试、接口、自动化、性能测试和日常文档编写办公有帮助的网站。 接口测试大力推荐国产的接口测试工具&#xff1a;apipost&#xff0c;apipost还是一款很不错的接口文档生产工…

OpenCV图像的基本操作

图像的基本操作&#xff08;Python&#xff09; 素材图 P1&#xff1a;die.jpg P2&#xff1a;cool.jpg V&#xff1a;rabbit.mp4&#xff0c; 下载地址 读取展示-图像 import cv2img_1 cv2.imread(./die.jpg) # default cv2.IMREAD_COLOR print("die.jpg shape(imre…

Python 实现自动化测试 dubbo 协议接口

前言 在工作或学习过程中&#xff0c;可能会遇到后端服务里有使用 dubbo 协议实现的接口&#xff0c;dubbo 协议接口的测试方法不同于 http/https 类型的接口&#xff0c;不能简单使用request.post的方法来完成自动化测试。 如果需要对 dubbo 协议的接口进行自动化测试&#…

数据结构篇-02:最小栈

对于这道题&#xff0c;除了 getMin 外的功能&#xff0c;传统的 栈 结构中都有&#xff0c;所以重点在于如何实现 getMin 方法。 有两类方法&#xff1a;使用辅助栈/不使用辅助栈 使用辅助栈的解法一 定义一个 栈 来实现常规功能&#xff0c;另外定义一个栈&#xff08;最小…

2016年认证杯SPSSPRO杯数学建模A题(第一阶段)洗衣机全过程文档及程序

2016年认证杯SPSSPRO杯数学建模 A题 洗衣机 原题再现&#xff1a; 洗衣机是普及率极高的家用电器&#xff0c;它给人们的生活带来了很大的方便。家用洗衣机从工作方式来看&#xff0c;有波轮式、滚筒式、搅拌式等若干种类。在此基础上&#xff0c;各厂商也推出了多种具体方案…

Flink多流转换(2)—— 双流连结

双流连结&#xff08;Join&#xff09;&#xff1a;根据某个字段的值将数据联结起来&#xff0c;“配对”去做处理 窗口联结&#xff08;Window Join&#xff09; 可以定义时间窗口&#xff0c;并将两条流中共享一个公共键&#xff08;key&#xff09;的数据放在窗口中进行配…

软考培训机构哪家比较好?各软考培训机构排名如何?

先放上机构测评图 一、机构情况 &#xff08;1&#xff09;主营业务 大多数软考培训机构主要致力于IT培训或者软件行业。这些机构的课程更加专业&#xff0c;因为他们起源于该行业。我相信报考软考的同学大部分也是从事这个行业的。个人认为选择这类机构进行培训会有更多好处…

图片保存后多了个水印?教你如何用华为手机保存无水印图片

对于各类生活App的深度用户来说&#xff0c;有时候碰到实用的生活技巧、攻略&#xff0c;甚至是一张好看的风景照&#xff0c;都会第一时间想要长按把图片保存到手机相册&#xff0c;有时候还会分享给朋友、朋友圈。 但是有些图片在App上显示的时候是干净的&#xff0c;保存下…

day30_回溯总结

文章目录 回溯的问题总结&#xff1a;1. 回溯三部曲&#xff1a;2. 回溯的模板3. 回溯题型4. 回溯的概念&#xff1a;5. 回溯的重点问题&#xff1a;组合和去重。[5.1 组合问题&#xff1a;](https://programmercarl.com/0077.%E7%BB%84%E5%90%88.html)剪枝优化[5.2 去重问题—…

接口自动化中如何完成接口加密与解密?

加密是一种限制对网络上传输数据的访问权的技术。将密文还原为原始明文的过程称为解密&#xff0c;它是加密的反向处理。在接口开发中使用加密、解密技术&#xff0c;可以防止机密数据被泄露或篡改。在接口自动化测试过程中&#xff0c;如果要验证加密接口响应值正确性的话&…

temu跨境电商怎么样?做temu蓝海项目有哪些优势?

在全球电商市场激烈的竞争中&#xff0c;Temu跨境电商平台以其独特的优势和策略&#xff0c;逐渐崭露头角。对于许多想要拓展海外市场的商家来说&#xff0c;Temu的蓝海项目提供了一个充满机遇的新平台。本文将深入探讨Temu跨境电商的优势以及在蓝海市场中的发展前景。 全球化市…

SpringBoot的自动装配原理

一、SpringBootConfiguration注解的作用 SpringBootApplication注解是SpringBoot项目的核心注解,加在启动引导类上。点击进去可以发现SpringBootApplication注解是一个组合注解。其中SpringBootConfiguration和EnableAutoConfiguration是由Spring提供的,剩下的注解是由JDK提供的…

牛客BC52 判断整数奇偶性(C语言)

#include <stdio.h> int main() {int a;while ((scanf("%d", &a)) ! EOF){ if (a%20)printf("Even\n");elseprintf("Odd\n");}return 0; }

跨平台Recorder录音插件:支持多种格式、音频可视化、实时上传、语音识别

视频教程地址&#xff1a;【跨平台Recorder录音插件&#xff1a;支持多种格式、音频可视化、实时上传、语音识别】 https://www.bilibili.com/video/BV1jQ4y1c7e4/?share_sourcecopy_web&vd_sourcee66c0e33402a09ca7ae1f0ed3d5ecf7c /** 先引入Recorder &#xff08; 需先…

Programming Abstractions in C阅读笔记:p254-p257

《Programming Abstractions in C》学习第70天&#xff0c;p254-p257总结&#xff0c;总计4页。 一、技术总结 1.minimax strategy(极小化极大算法) p255, This idea–finding the position that leaves your opponent with the worst possible best move–is called the mi…

MiniTab的单值的变量控制图——I-MR 控制图分析

单值的变量控制图分为&#xff1a;I-MR 控制图、Z-MR 控制图、单值控制图、移动极差控制图4种。 I-MR 控制图 功能菜单请选择&#xff1a;统计>控制图>单值的变量控制图>I-MR。 使用 I-MR 控制图 可以在拥有连续数据且这些数据是不属于子组的单个观测值的情况下监视…

Supervised Contrastive 损失函数详解

有什么不对的及时指出&#xff0c;共同学习进步。(●’◡’●) 有监督对比学习将自监督批量对比方法扩展到完全监督设置&#xff0c;能够有效地利用标签信息。属于同一类的点簇在嵌入空间中被拉到一起&#xff0c;同时将来自不同类的样本簇推开。这种损失显示出对自然损坏很稳…