什么是库?
库是一组预先编译好的方法/函数的集合,其他程序想要使用源文件中的函数时,只需在编译可执行程序时,链接上该源文件生成的库文件即可。
库分为两类:静态库和动态库
- 在Linux系统中,以
.a
为后缀的是静态库,以.so
结尾的是动态库。 - 在Windows系统中,以
.lib
为后缀的是静态库,以.dll
结尾的是动态库。
那么这两种库有什么区别呢?
1. 静态库: 在使用g++编译程序时,会根据库和我们写的源文件,最终生成一个可执行程序。 静态库也放入可执行程序中,每个可执行程序单独拥有一个静态库。体积较大,但执行效率较高。
2. 动态库: 在使用g++编译程序时,会根据库中相关函数的索引表和我们写的源文件,最终生成一个可执行程序。每个可执行程序中只拥有相关函数的索引表,当程序执行到对应函数时,会根据索引表,动态寻找该函数的位置,然后调用。体积较小,但执行效率较低。 由于多个程序共享同一个动态库,因此动态库也叫共享库。
库的制作与使用
静态库
- 编译生成静态库
g++ -c ***.cpp -o ***.o # 只编译,不链接生成二进制文件
ar -crs lib***.a ***.o # 编译生成静态库
# 如果有多个.o文件共同编译生成静态库,则将所有.o文件都写在后面
ar -crs lib***.a ***.o xxx.o ...
指令解释:
- ar:用于生成静态库的指令
- ar -c:用于创建静态库
- ar -r:将文件插入或者替换静态库中同名文件
- ar -s:重置静态库索引
- 使用静态库
g++ main.cpp -L 库的路径 -l库名 -I 头文件的路径 # 库名的前面需要加上l字母
# 如果库所在的路径和头文件所在的路径为当前路径,则可以使用 “.” 来简化书写
g++ main.cpp -L . -l库名 -I . 路径
动态库
- 编译生成动态库
g++ -fPIC -c ***.cpp -o ***.o # 编译生成二进制文件
g++ -shared ***.o -o lib***.so # 依赖于二进制文件生成一个动态库
# 上面两个指令可以合成一条指令
g++ -fPIC -shared ***.cpp -o lib***.so
- 使用动态库(和使用静态库命令相同)
g++ main.cpp -L 库的路径 -l库名 -I 头文件的路径 # 库名的前面需要加上l字母
# 如果库所在的路径和头文件所在的路径为当前路径,则可以使用 “.” 来简化书写
g++ main.cpp -L . -l库名 -I . 路径
如果使用上述命令后生成了可执行程序,但是使用动态库时却报错了:
可以尝试以下解决方案:
- 更改路径的宏
export LD_LIBRARY_PATH=库的路径
- 将自己的动态库放到系统的库函数目录中(/lib64或/usr/lib64)
# 由于该操作需要管理员权限,因此需要在命令之前加上sudo
# 这两个命令都可以
sudo mv 动态库文件名称 /lib64
sudo mv 动态库文件名称 /usr/lib64