库的创建和使用
- 静态库:libxxx.a
一个文件内部如下:
包含着一个头文件head.h,这个头文件里面写着一些函数的声明:如下:
#ifndef _HEAD_H #define _HEAD_H // 加法 int add(int a, int b); // 减法 int subtract(int a, int b); // 乘法 int multiply(int a, int b); // 除法 double divide(int a, int b); #endif
src包含着一些head内部函数实现的一些函数,如除法div.c:
#include <stdio.h> double divide(int a, int b) { return (double)a/b; } ~
首先进入src目录下需要使用命令gcc -c *.c将所有的.o文件,注意这里的sub.c包含了头文件head,所以要找到这个头文件所在的位置,也就是包含这个头文件的目录,用-I(大写i)后面接路径
其次是用命令将所有的.c文件打包,ar rcs libxxx.a *.o,这里是生成一个库文件libcalc.a,再将库移动到lib目录下
得到的效果如下:
在最后一步就是执行main.c,一般我们直接使用gcc main.c -o app生成可执行文件即可,但是这里的main.c如下所示:它包含了head.h这个头文件,所以执行的时候要知道这个头文件的位置和它是怎么实现的(也就是库),对于头文件head.h我们只要知道它在哪个路径就好了,但是库我们除了要知道哪个路径也要知道它的库名。
所以直接用命令:
calc,就能运行出结果了。#include <stdio.h> #include "head.h" int main() { int a = 20; int b = 12; printf("a = %d, b = %d\n", a, b); printf("a + b = %d\n", add(a, b)); printf("a - b = %d\n", subtract(a, b)); printf("a * b = %d\n", multiply(a, b)); printf("a / b = %f\n", divide(a, b)); return 0; }
-
动态库:libxxx.so
得到一个与位置无关的可执行文件:
gcc -c -fpic *.c -o
将得到的.o文件打包在一个动态库,这里注意和静态库的区别,这里用的仍然是gcc命令
gcc -shared *.o -o libcalc.so,并将该库放在library下的lib文件里,得到的结果如下所示:
这时候就可以执行了,

此时生成了main的可执行文件,
但是此时会出现以下的错误:

即当加载动态库的时候无法打开这个库
-
解决动态库加载失败的原因:
使用命令ldd main可以查看绑定的动态库以及它的途径(这里的app1就是那个main,因为文档分成两次写的):

原因是因为动态库是一个共享库,即使你生成了可执行文件,但是运行的时候虽然知道库的名字,但是还是要定位到动态库,系统的动态载入器来获取绝对路径,对于elf格式的可执行程序,可以由id-linux.so来完成,他先后搜索elf文件的DP_RPATH段---->环境变量LD_LIBRARY_PATH---->/etc/id.so.cache文件列表------>/lib/,/user/lib目录找到库文件后载入内存。使用命令:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:(这放的绝对路径)
比如这里的动态库的位置是/home/nowcoder/linux/library/lib,那么把它放在上面的命令的绝对路径位置就可以执行app1,也就是main了。
但是这个时候只是临时的决解了这个问题,要是重新关闭终端再次打开终端就会失效,我们要是想它永久有效,就要回到目录nowcoder@nowcoder:~$下,使用命令ll找到.bashrc这个文档,vim .bsahrc之后在最后一行加上
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:(这放的绝对路径) -

浙公网安备 33010602011771号