贵阳微网站建设公司,网站建设用书,如何学网站建设,中装建设算力租赁前言#xff1a;
本期我将要给大家讲解的是有关 动态库和静态库 的相关知识#xff01;#xff01;#xff01; 目录
序言
见一见库
为什么要有库
#xff08;一#xff09;动态库#xff08;.so#xff09;
1.基本概念
2.命名规则
3.制作动态库
#xff0…前言
本期我将要给大家讲解的是有关 动态库和静态库 的相关知识 目录
序言
见一见库
为什么要有库
一动态库.so
1.基本概念
2.命名规则
3.制作动态库
二静态库.a
1.基本概念
2.命名规则
3.制作静态库
三什么叫 fPIC
四对比静态库和动态库
总结 序言
见一见库 本质上来说库是一种可执行代码的二进制形式可以被操作系统载入内存执行。库有两种静态库.a、.lib和 动态库.so、.dll。 所谓静态、动态是指链接。简单回顾一下将一个程序编译成可执行程序的步骤 在正式的讲解动态库和静态库之前我们先带带大家认识我们平时写 C/C代码时用到的库 ls /usr/lib64/libc* ” 这个命令用于列出匹配模式 libc* 的文件或目录 其次我们也可以去查看平时我们经常用到的 【解释说明】
系统已经预装了C/C的头文件和库文件头文件提供方法说明库提供方法的实现头和库是有对应关系的是要组合到一起使用的头文件是在预处理阶段装入的链接本质其实就是链接库 为什么要有库
其实这一点大家都能理解造轮子和用轮子的问题
库是一组预先编写好的代码、程序或函数的集合用于解决特定类型问题或提供特定功能这些代码通常被封装成模块以便在开发软件时能够重用、共享和简化代码。
在我们学习阶段大家可以更多的尝试去造轮子熟悉其中的一些思想及其方法等等到大家上班的就是 “用轮子” 的较多了。 一动态库.so
1.基本概念
动态库是一种在运行时加载和链接的库文件与静态库相比动态库在程序执行之前不会被完全链接到可执行文件中而是在运行时被动态地加载到内存并链接。
2.命名规则
在命名动态库时通常会遵循一定的命名规则以确保一致性和可读性。以下是一些常见的动态库命名规则 前缀动态库名称通常以lib开头作为前缀表示这是一个库文件。 中间部分中间部分通常是描述库的名称或功能的字母数字组合。可以根据库的用途或模块来命名以便更好地理解其功能。建议使用小写字母和下划线进行命名以增加可读性。 扩展名动态库的扩展名取决于操作系统和平台。在Linux上通常是.so共享对象在Windows上通常是.dll动态链库在Mac上通常是.dylib动态库。 综合起来一个典型的动态库命名可能如下所示 3.制作动态库 在Linux系统上创建动态库也称为共享库或.so文件涉及编写、编译和链接一组源代码文件以生成可在多个应用程序之间共享的动态链接库。 以下是创建Linux动态库的一般步骤
1️⃣编译源代码
使用编译器将源代码编译成位置无关的目标文件通常使用.o文件扩展名。为了生成动态库需要使用 -fPIC 选项位置无关代码来确保目标文件可以在内存中加载并重定位。
例如在Linux系统上可以使用gcc编译器编译一个源文件并生成位置无关的目标文件 2️⃣创建动态库
使用共享库工具gcc也可以用于此将目标文件链接到一个共享库文件中。通常Linux动态库的命名约定是以.so结尾并且通常有版本号。
以下是创建动态库的示例命名为 libmymath.so 3️⃣运行代码
我这里是把文件打包拷贝到 【otherPerson】目录下执行 紧接着执行gcc -o mytest main.c 发现报错了 【解释说明】
因为在当前路径下头文件并没有找到因为并没有进行安装 接下来再次执行gcc -o mytest main.c -I include 发现还是报错了 【解释说明】
因为在当前路径下库并没有找到 接下来再次执行gcc -o mytest main.c -I include -L lib发现还是报错了 接下来再次执行gcc -o mytest main.c -I include -L lib -lmymath发现还是报错了 这次我们发现程序正常运行成功了。紧接着我们执行相应的文件 【解释说明】
此时有的小伙伴可能就比较疑惑“我不是已经告诉了系统我的库在哪里并且告诉叫什么了吗为什么还是找不到呢”其实gcc时只是告诉了编译器而没有真正的告诉操作系统运行的时候因为我的 .so 并不是在默认的路径下所以os 依旧找不到 ⭐️ 如何让系统能够找到动态库 1、通过环境变量临时方案 环境变量中确实没有我们当前的路径因此第一种解决方法就是把我们当前的路径加入到系统的环境变量中。具体如下 但是这个方法是临时性的当我们重新打开去运行时就失效了 2、指定路径下建立软链接永久版本 3、配置文件方案
在配置之前需要先把上述使用软链接创建的删除掉 如果安装在其他目录需要将其添加到/etc/ld.so.conf.d/文件中步骤如下
1.前期准备 2.编辑/etc/ld.so.conf文件加入库文件所在目录的路径 3.运行ldconfig 该命令会重建/etc/ld.so.conf.d/文件 二静态库.a
1.基本概念
静态库是一种在编译时链接到可执行程序的库文件形式它是由一组预编译的目标文件Object File组成其中包含了函数、变量和其他可重用的代码和数据。 需要注意一点库云服务器默认没有静态 2.命名规则
在 Linux 上静态库的命名规则通常是
liblibrary_name.a其中
lib 是固定的前缀表示这是一个库文件。library_name 表示该库的名称或功能建议使用小写字母和下划线进行命名以增加可读性。.a 是静态库的扩展名表示这是一个归档文件 (archive file)。静态库通常以 .a 作为扩展名。 综合起来一个典型的动态库命名可能如下所示 3.制作静态库 创建静态库涉及编写、编译和打包一组代码文件以便它们可以在其他程序中静态链接和重用。 以下是创建静态库的一般步骤
1、编写使用创建的静态库的测试代码
/myadd.h/#ifndef __ADD_H__#define __ADD_H__ int add(int a, int b); #endif // __ADD_H__/myadd.c/#include myadd.hint add(int a, int b){return a b;}/mysub.h/#ifndef __SUB_H__#define __SUB_H__ int mysub(int a, int b); #endif // __SUB_H__/mysub.c/#include mysub.hint sub(int a, int b){return a - b;}///main.c#include stdio.h#include myadd.h#include mysub.hint main(){int a 10;int b 3;printf(add(10, 3)%d\n, a, b, add(a, b));printf(add(10, 3)%d\n, a, b, sub(a, b));return 0;}
2、使用编译器将源代码编译成目标文件通常是中间代码文件编译时使用适当的编译选项以确保生成的目标文件是可链接的注意带参数-c否则直接编译为可执行文件 3、然后通过ar工具将目标文件打包成.a静态库文件 【注意】 大一点的项目会编写makefile文件CMake等等工程管理工具来生成静态库输入多个命令太麻烦了 4、Linux下使用静态库只需要在编译的时候指定静态库的搜索路径-L选项、指定静态库名不需要lib前缀和.a后缀-l选项 【注意】 -L表示要连接的库所在目录 -l指定链接时需要的动态库编译器查找动态连接库时有隐含的命名规则即在给出的名字前面加上lib后面加上.a或.so来确定库的名称。
【小结】
创建静态库涉及编写、编译、打包目标文件然后将静态库链接到其他程序中这种方法适用于小型项目或者当需要确保可执行文件与特定版本的库一起分发时但需要注意的是静态库会增加可执行文件的大小并且不支持动态更新。如果需要更大的灵活性和共享性可以考虑使用动态库。 三什么叫 fPIC fPIC 是 GCC编译器的一个选项用于生成位置无关代码Position Independent CodePIC。位置无关代码是一种可以在内存中加载并且不受加载地址限制的代码因此适合用于创建共享库动态链接库也称为.so文件以及在多个进程之间共享的代码。 我们以下图进行分析 【解释说明】
当一个库真正的映射到地址空间的时候它的起始地址才能真正的被确定下来而它的库在形成的时候并不是使用的绝对地址而是使用的相对于起始地址的偏移量有了上述这样的方法使得动态库在进程的地址空间中能够随便的进行加载而与我们加载到地址空间的什么位置毫无关系。因为OS是知道起始地址的因此在我们链接时只需把对应的偏移量加载进来OS根据起始地址 偏移量的操作即可完成相应的地址映射上述这样的库就称为动态库这种库中的地址就称为 fPIC。 四对比静态库和动态库
动态库和静态库是两种不同的库文件类型它们在编程和软件开发中有着重要的区别。以下是它们之间的主要区别 加载时机: 静态库在编译时将库的代码和数据链接到可执行文件中形成一个单独的可执行文件。这意味着库的代码在程序运行之前已经完全被包含在可执行文件中。动态库库的代码和数据在程序运行时才被加载到内存中。可执行文件包含了对库的引用但实际的库代码在程序启动时或首次使用时才会被加载。 文件大小: 静态库由于库的代码被完全复制到每个可执行文件中因此可执行文件通常比较大。动态库多个可执行文件可以共享相同的库因此动态库可以减小可执行文件的大小。 内存占用: 静态库每个运行的程序实例都包含库的一个拷贝因此可能会占用更多的内存。动态库多个程序实例可以共享同一个库的实例节省内存。 可扩展性: 静态库每次引入新的库版本都需要重新编译和链接不够灵活。动态库可以在不修改可执行文件的情况下替换或升级库的版本提供更好的可扩展性。 加载速度: 静态库由于库的代码已经包含在可执行文件中因此加载速度较快。动态库需要在运行时加载可能会略微减慢程序启动速度。 总结 以上便是本文关于动静态的全部内容了。接下来简单的回顾总结一下 动态库和静态库各自有其优势和劣势具体选择取决于项目的需求和设计考虑通常动态库在节省内存、库的更新和维护方面更有优势而静态库在加载速度和跨平台兼容性方面更有优势。