24 静动态库

首先创建两个函数的头文件和源文件

最后的main函数

cpp 复制代码
#include <stdio.h>
#include "print.h"
#include "sum.h"

int main()
{
    Print("时间");
    printf("%d\n", sum(3, 5));
    return 0;
}

将函数编译成.o文件

make生成文件

make hello分类文件

测试文件夹只留一个main.c

概念

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

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

一个鱼胴体阿酷链接的可执行文件仅仅包含函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码

在可执行文件开始运行之前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamic linking)

动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间,操作系统采用虚拟机制允许物理内存中的一份动态库被拥戴该库的所有进程共用,节省了内存和磁盘空间

如何写

静态库

ar -rc lib库名.o 打包的文件1 打包的文件2

makefile

cpp 复制代码
libhello.a: print.a sum.o
	ar -rc libhello.o print.o sum.o
print.o: print.c
	gcc -c print.c
sum.o: sum.c
	gcc -c sum.c
.PHONY:hello 
hello:
	mkdir -p hello/lib 
	mkdir -p hello/include
	cp -rf *.h hello/include
	cp -rf *.a hello/lib 
.PHONY:clean
clean:
	rm -rf *.o libhello.a hello

动态库

编译成与位置无关的二进制文件

gcc -fPIC -c 文件名

动态库对位置的描述是相对位置,段地址+偏移

readelf -S 二进制文件

上面没有具体地址,只有偏移量

生成动态库

gcc -shared 二进制文件 -o 库名

makefile

cpp 复制代码
libhello.so: print.o sum.o
	gcc -shared print.o sum.o -o libhello.so
print.o: print.c
	gcc -fPIC -c print.c
sum.o: sum.c
	gcc -fPIC -c sum.c
.PHONY:hello 
hello:
	mkdir -p hello/lib 
	mkdir -p hello/include
	cp -rf *.h hello/include
	cp -rf *.so hello/lib 
.PHONY:clean
clean:
	rm -rf *.o libhello.so hello

如何用

静态库

1.拷贝到系统头文件路径下

头文件gcc的默认路径是: /usr/include

库文件的默认搜索路径是: /lib64 or /usr/lib64

sudo cp hello/include/* /usr/include -rf

sudo cp hello/lib/libhello.a /lib64 -rf

拷贝库到系统默认路径下,叫库的安装

删除系统默认路径的库,叫库的卸载

gcc main文件 -l库名 //库名不包含lib和后缀

2.指定库位置

gcc main.c -I 头文件路径 -L 库文件路径 -l指定库名

3.lib64下创建动态库的软连接

ln -s 动态库名 /lib64/建立名

4.把库的路径,加载到环境变量的步骤放在登录脚本中

根目录下的.bashrc文件夹,登录时可以自动导入环境变量

vim ~/.bashrc

这个文件时被.bash_profile启动的

改配置文件如果出错,登录就会出错,要小心

动态库

如果动态库和静态库都有,默认链接动态库,只有静态库,会选择静态库

1.指定库位置

gcc main.c -I 头文件路径 -L 库文件路径 -l指定库名

如果要使用静态库,需要带参数-static在最后

动态库运行还需要告诉系统库在哪,ldd显示依赖的库,动态库找不到

1.将库拷贝到/lib64目录下

2.环境变量

echo $LD_LIBRARY_PATH //加载库的搜索路径

复制库的路径加入到这个环境变量中

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库目录 //不能直接=,要拼接到原环境变量的后面,:号分割

环境变量存在配置文件里,每次登录都会读取配置,所以下次环境变量中库就会消失

保存环境变量配置文件

在下列目录创建一个.conf文件,输入库目录

sudo vim /etc/ld.so.conf.d/文件名

生效配置文件

sudo ldconfig

动态库的加载

程序和动态库可以分批加载,库通过页表映射到栈堆中间的共享区,代码需要执行库的时候,到共享区找到内存中的函数,执行完后返回继续运行

动态库只需要一份,可以被多次使用,所以节省空间,静态库每一次使用都是一次拷贝

为什么要有库

站在使用库的角度,库的存在,可以大大的减少开发周期,提高软件本身的指令

对于写库的人:1.简单,方便使用 2.代码安全,不用公开

库推荐

ncurses 字符界面库

boost 准标准库

相关推荐
前端环境观察室9 分钟前
别只看 task success:AI Agent 浏览器自动化真正要补的是环境证据链
前端·后端
浩风祭月14 分钟前
把 Docker 镜像从 2GB 瘦身到 180MB,AI 帮我找到了那些看不见的“脂肪”
后端·ai编程
jscxy520632 分钟前
ospf综合实验
运维·服务器·网络
慵懒的猫mi39 分钟前
deepin 25部署x11vnc+xrdp,实现vnc和mstsc双重访问
linux·windows·开源软件·deepin
KaMeidebaby43 分钟前
卡梅德生物技术快报|酵母双杂交 cDNA 文库构建与蛋白互作筛选流程
服务器·前端·数据库·人工智能·算法
csdn_aspnet1 小时前
Modbus TCP C# 客户端程序
服务器·网络·tcp/ip·c#
沐风___1 小时前
App 上架之后:如何看数据、获取用户与持续迭代产品
服务器·前端·数据库
小灰灰搞电子1 小时前
Rust 实现异步ModbusTCP主机源码分享
服务器·网络·modbustcp·rust
apcipot_rain1 小时前
计科八股20260529——连接协议连接线程池、模块拆解模块通信、WebSocket
运维·服务器·网络·八股
AAA大运重卡何师傅(专跑国道)1 小时前
力扣hot100
服务器·前端·数据库