0x04_静态库/动态库制作
静态库
静态库名字以lib开头,以.a结尾。
静态库制作步骤:
-
写好源代码。
-
编译源代码生成
.o
文件。gcc -c add.c -o add.o gcc -c sub.c -o sub.o
-
制作静态库
ar rcs libname.a add.o sub.o ...
使用静态库:
gcc test.c libname.a -o a.out
静态库使用时,是直接编译到文件里的。
头文件对应
对于未定义未声明的函数,编译器隐式声明返回值为int的形式。如果函数不是返回的int,则隐式声明失效,会报错。
使用头文件的方法加载静态库:
#ifndef _MYMATH_H_
#define _MYMATH_H_
int add(int, int);
int sub(int, int);
#endif
gcc test.c libmymath.a -o test
如果静态库和头文件在其他目录:
gcc test.c ./lib/libmymath.a -o a.out -I ./inc
动态库
写在源代码里面的函数,相对main函数偏移是一定的,链接时,回填main函数地址后,其源代码里的函数也就得到了地址。
动态库里的函数会用一个@plt来标识,当动态库加载到内存时,再用加载进去的地址将@plt替换掉。
动态库制作步骤:
-
写好源代码。
-
编译源代码生成
.o
文件,生成与位置无关的代码。gcc -c add.c -o add.o -fPIC gcc -c sub.c -o sub.o -fPIC
-
制作动态库。
gcc -shared -o libname.so add.o sub.o
使用动态库:-l指定库名,-L指定库路径,库名要去掉lib和.so
gcc test.c -o a.out -l name -L ./lib -I ./inc
执行a.out出错。
./a.out
./a.out: error while loading shared libraries: libname.so: cannot open shared object file: No such file or directory
错误分析
链接器:工作于链接阶段,工作时需要-l和-L。
动态链接器:工作于程序运行阶段,工作时需要提供动态库所在目录位置。
-
需要指定动态库路径并使其生效,再执行文件,可通过环境变量指定:
export LD_LIBRARY_PATH=./lib
但仅在当前终端生效,因为环境变量是进程的概念,关闭终端后再打开,是两个进程,环境变量发生了变化。要想永久生效,需要修改bash的配置文件:
vi ~./bashrc
,追加export LD_LIBRARY_PATH=./lib(一般写绝对路径)
。修改后需要使配置文件立即生效:. ~/.bashrc 或 source .bashrc 或 重开终端
-
拷贝自定义动态库到/lib(标准C库所在目录位置)。
-
配置文件:
sudo vi /etc/ld.so.conf 写入动态库绝对路径,保存 sudo ldconfig -v 使得配置文件生效
使用ldd a.out查看程序是否动态链接成功。