库
就是可复用的二进制可执行代码的有序集合。
编译c文件时可以用 gcc -L库文件地址 -l库文件名称 来使用动态库和静态库。
静态库
使用静态库的程序,在编译链接时载入静态库的代码,并将静态库的代码置入编译出的可执行程序。文件格式为:libxx.a ,其中lib是前缀,.a为文件后缀。
动态库
使用动态库的程序,在编译链接的过程仅对动态库做简单引用,在程序运行时才将共享库的代码载入内存。文件格式为:libxx.so,其中lib是前缀,.so为文件后缀。
举个例子,下面程序能够计算n个浮点数的平均值:
imath.c
float AVE(int *a,int len){
int i;
float re=0;
for(i=0;i<len;++i){
re+=a[i];
}
re/=len;
return re;
}
cacul.c
#include<stdio.h>
#include"imath.h"
int main()
{
int n,i;
int a[150];
float re=0;
scanf("%d",&n);
for(i=0;i<n;++i){
scanf("%d",&a[i]);
}
re=AVE(a,n);
printf("%.2f\n",re);
}
imath.h
#ifndef AL_H
#define AL_h
float AVE(int *a,int len);
#endif
在ubuntu下编译运行
1.不使用库:
执行命令:
gcc imath.c cacul.c -o main
./main
结果如下:
这里我们先编译链接好源程序,然后运行。先输入2 代表求 两个数的平均值,接下来输入要求的两个数,结果为3.50.
2.使用静态库
可以先将imath.c编译成imath.o文件,再将其打包为库文件,当我们要编译链接cacul.c时再使用该库。
执行命令:
gcc -c imath.c
ar rc libimath.a imath.o
gcc cacul.c -o main -L. -limath
结果如下:
ar命令可以用来建立,修改库,rc为参数。
gcc -L. 是指当前目录 -limath 是指定imath库
3.使用动态库
执行命令
gcc -shared -fpic -o libmat.so imath.c
gcc cacul.c -o main2 -L. -lmat
./main
-shared生成共享目标文件。-fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。
结果如下:
发现出错了,原因是找不到库文件。
我们执行下面命令:
sudo mv libmat.so /usr/lib
此命令需要超级管理员权限,执行完后就发现程序可以正常运行了,因为我们把libmat.so文件移入到/usr/lib目录下, /usr/lib是默认存放的动态库,这样程序就能成功加载动态库代码了。