库的概念:
一种可执行代码的二进制形式,可以被操作系统载入内存执行。
库的意义:
① 可以复用,可以使用但遵守许可协议。② 共享库的好处是:不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。
例子:
代码文件:
a.h
#ifndef A_H
#define A_H
float myavg(int x1,int x2,int x3);
int mysum(int x1,int x2,int x3);
#endif //A_H
main.c
#include "a.h"
int main()
{
int x1,x2,x3;
float avg;
int sum;
printf("请输入三个整数,以空格隔开:\n");
scanf("%d %d %d",&x1,&x2,&x3);
avg=myavg(x1,x2,x3);
printf("the average is: %5.2f\n",avg);
sum=mysum(x1,x2,x3);
printf("the sum is:%d\n",sum);
return 0;
}
myavg.c
#include<stdio.h>
float myavg(int x1,int x2,int x3){
float avg;
avg=(float)(x1+x2+x3)/3;
return avg;
}
mysum.c
#include<stdio.h>
int mysum(int x1,int x2,int x3)
{
int sum=0;
sum=x1+x2+x3;
return sum;
}
静态库的产生:
静态库的后缀是.a,它的产生分两步:
① 由源文件编译生成一堆.o,每个.o里都包含这个编译单元的符号表。
② ar命令将很多.o转换成.a,成文静态库。
文件:mysum.c myavg.c main.c a.h
gcc myavg.c mysum.c -c
ar -crs libjs.a myavg.o mysum.o
gcc main.c -c
gcc main.o -L./ -ljs -o main //注意:-L 指定库所在路径,若不指定,默认 /lib 或 /usr/lib
./main
动态库(共享库)的产生:
命名:动态库名称格式:lib*.so
其中lib为前缀;.so代表动态库;*表示有意义的名称。例如:helloworld动态库,那么它的名称就是libhelloworld.so
共享库制作:
编译时采用的编译选项为:
-fpic:位置无关代码选项(position-independent code)
-shared:共享库
例子:
文件:mysum.c myavg.c main.c a.h
gcc myavg.c mysum.c -c
gcc -shared -o libjs.so myavg.o mysum.o
gcc main.c -c
gcc main.o -L./ -ljs -o main //指定连接时库所在路径,若不指定,默认/lib 或 /usr/lib
./main
此处会出现错误信息
解决方案:
①
libjs.so复制到/usr/lib或者 /lib 目录下
cp libjs.so /usr/lib 或者 cp libjs.so /lib
②
使用 ldd 命令查看 main 所依赖的动态链接库
# ldd main
如果查看到 libjs.so = > not found 说明没有找到
则需添加路径。命令如下:
# export LD_LIBRARY_PATH= 绝对路径
总结:
命名:
在linux下,库文件一般放在/usr/lib和/lib下,
静态库的名字一般为libxxxx.a,其中xxxx是该lib的名称
动态库的名字一般为libxxxx.so.major.minor,xxxx是该lib的名称,major是主版本号, minor是副版本号
Idd:
ldd命令可以查看一个可执行程序依赖的共享库,
例如# ldd /bin/lnlibc.so.6
=> /lib/libc.so.6 (0×40021000)/lib/ld-linux.so.2
=> /lib/ld- linux.so.2 (0×40000000)
可以看到ln命令依赖于libc库和ld-linux库