【C】静态链接和动态链接

一、静态库和动态库

Linux的库文件一般分为静态库和动态库:

静态库(.a): 库文件以.a为后缀,程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库 动态库(.so): 库文件以.so为后缀,程序运行的时候才会去链接动态库的代码,多个程序共享使用库的代码

二、理解库

如果不想给对方我们的源代码,我们可以选择给用户提供我们的.o可重定位目标二进制文件(gcc -c 文件)与.h头文件。让用户用我们提供的.o文件进行链接即可。在编译时,只要把源文件编译成.o文件在将其链接便可形成一个可执行的程序

通过 gcc -o 链接目标文件,生成可执行程序:

我们可以把 .o.h 文件提交给用户,可是如果有成百上千个,那一个个提供太过麻烦。因此为了让用户简单的使用库,我们就把所有 .o文件打包成一个包,给对方提供一个库文件即可。把多个文件合并成一个文件,这个文件就是库,打包的方式就分为了静态库和动态库。

三、制作静态库

创建Makefile

c 复制代码
libmymath.a: my_add.o my_sub.o
		ar -rc $@ $^

my_add.o: my_add.c
		gcc -c my_add.c -o my_add.o

my_sub.o: my_sub.c
		gcc -c my_sub.c -o my_sub.o

.PHONY: output
output:
		mkdir -p mylib/include
		mkdir -p mylib/lib
		cp -f *.a mylib/lib
		cp -f *.h mylib/include

.PHONY: clean
clean:
		rm -rf *.o libmymath.a

在Makefile中,$@$^是自动变量,用于表示规则中的目标和依赖项。

  • $@表示当前规则的目标(target),即规则左侧的文件名。
  • $^表示当前规则的所有依赖项(prerequisites),即规则右侧的文件名。

在Makefile中,libmymath.a: my_add.o my_sub.o规则中的 $@ 表示 libmymath.a,即目标文件名。$^ 表示 my_add.o my_sub.o,即所有依赖项的列表。

当执行命令时,$@$^会被替换为实际的目标和依赖项的文件名,以便进行相关操作。例如,ar -rc $@ $^ 中的 $@ 将被替换为 libmymath.a$^ 将被替换为 my_add.o my_sub.o。因此,该命令最终将执行 ar -rc libmymath.a my_add.o my_sub.o,将 my_add.omy_sub.o 打包成 libmymath.a 静态库。

output 是我们要生成的库

链接库:

c 复制代码
 gcc -o mytest my_test.c  -I ./mylib/include -L ./mylib/lib -lmymath

-I:指明头文件的搜索路径

-L:指明库文件的搜索路径

-l:指明要链接哪个库,带上库的名称(去掉前缀和后缀)

四、制作动态库

首先我们需要把库文件全部编译成.o文件,这里与静态库不同,需要带上选项 -fPIC,形成与位置无关码:

c++ 复制代码
gcc -c -fPIC my_add.c

动态库打包:-shared

c++ 复制代码
gcc -shared -o libmymath.so my_add.o my_sub.o

目录结构:

c 复制代码
➜  test tree
.
├── libmymath.so
├── Makefile
├── my_add.c
├── my_add.h
├── my_add.o
├── mylib
│   ├── include
│   │   ├── my_add.h
│   │   └── my_sub.h
│   └── lib
│       └── libmymath.so
├── my_sub.c
├── my_sub.h
├── my_sub.o
├── mytest
└── my_test.c

链接动态库:

c 复制代码
gcc -o mytest my_test.c -I mylib/include -L mylib/lib  -lmymath

报错了:

我们此时已经告诉了库文件,路径和库名称,选项已经给gcc带上了。但是我们当编译完之后,和gcc还有关系吗?答案是无关的,接下来运行是和OS有关的,动态库是运行时才加载的,所以程序运行起来,OS和shell也是需要知道库是在哪里的!而我们自己制作的库并没有在系统路径下,OS无法找到!如何找到动态库。

把库路径添加到环境变量LD_LIBRARY_PATH:

c 复制代码
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/zmm/playground/test/mylib/lib
相关推荐
byte轻骑兵6 小时前
【C++特殊工具与技术】优化内存分配(四):定位new表达式、类特定的new、delete表达式
开发语言·c++
广州正荣7 小时前
成绩管理革新者:C++驱动的智能数据处理平台
c++·人工智能·科技
90wunch7 小时前
对象回调初步研究
c++·windows·安全
Se_ren_di_pity7 小时前
C++ STL容器汇总
开发语言·c++
Wendy_robot7 小时前
【零基础勇闯嵌入式岗】从单片机低功耗中获得的启发
c++·单片机·嵌入式硬件
lul~10 小时前
[科研理论]无人机底层控制算法PID、LQR、MPC解析
c++·人工智能·无人机
我命由我1234511 小时前
STM32 开发 - 中断案例(中断概述、STM32 的中断、NVIC 嵌套向量中断控制器、外部中断配置寄存器组、EXTI 外部中断控制器、实例实操)
c语言·开发语言·c++·stm32·单片机·嵌入式硬件·嵌入式
CodeWithMe12 小时前
【软件开发】上位机 & 下位机概念
c++
luofeiju12 小时前
数字图像处理与OpenCV初探
c++·图像处理·python·opencv·计算机视觉
whoarethenext12 小时前
使用 C/C++的OpenCV 将多张图片合成为视频
c语言·c++·opencv