1、库
所谓的库就是一种可执行代码的二进制形式,可以被操作系统载入内存执行。
2、静态库和动态库
静态库 .a
文件的命名方式:“libxxx.a”,库名前加“lib”,后缀是“.a”,库名是“xxx”
链接时间:静态库的代码是在编译过程中被载入到程序中的
链接方式:静态库的链接是将整个函数库的所有数据都合成进了目标代码,优点是编译后的执行程序不需要外部的函数库支持,因为所使用的函数已经被编进去了;缺点是如果所使用的静态库发生更新改变,则需要重新编译生成静态库。
动态库 .so
文件命名方式:“libxxx.so”,库名前加“lib”,后缀是“.so”,库名是“xxx”
链接时间:动态库在编译时并没有被编译进目标代码,而是当你的程序执行到相关函数的时候才调用该函数库里的相应函数。缺点是函数库并没有整合进程序,所以程序的运行环境必须提供相应的库;优点是动态库的改变不影响程序。
二者的区别:同一个程序分别使用静态库和动态库生成两个可执行文件时,静态库链接所生成的那个可执行文件要比动态库链接所生成的可执行文件占用的空间大。
3、静态链接库和动态链接库的生成
(1)生成一个可执行文件
hello.c
//hello.c 函数库的源程序,打印hello world!
#include
int main()
{
printf("hello world!\n");
return 0;
}
生成一个hello.o文件,该文件是将源文件编译生成的汇编文件,在链接之前该文件是不可执行的,生成.o文件的命令为:
gcc -c hello.c
生成一个hello的可执行文件,格式为ELF
gcc -o hello hello.c
此时,hello为一个可执行文件,执行结果如下
(2)静态库
准备三个文件 hello.c hello.h test.c
//hello.c 打印hello world
#inlcude "hello.h"
void hello()
{
printf("hello world!\n");
}
//hello.h
#include
void hello();
//test.c 测试程序,调用hello函数打印hello world
#include "hello.h"
int main()
{
hello();
return 0;
}
使用如下命令,将hello.c生成hello.o的汇编文件
gcc -c hello.c
由.o文件生成.a的静态库文件,静态库的名字问libhello.a
ar rc libhello.a hello.o
使用静态库进行静态链接,生成可执行文件hello
gcc -o test test.c -L. -lhello
-L 是指定加载库文件的路径
-l 指定加载的库文件
生成的可执行文件是test,运行一下
(3)动态库
还是用上面的三个文件
生成.o文件
gcc -c hello.c
生成动态库
gcc -fPIC -shared -o libhello.so hello.c
链接生成可执行文件
gcc -o test test.c -L. libhello.so
生成的可执行文件是test,./test执行可执行文件时报如下错
因为执行程序找不到libhello.so
用:ldd test命令查看libhello.so库,发现其找不到
原因是在 /etc/ld.so.conf 文件中设置了动态链接库了寻找路径
可以看到有很多路径设置文件,在ld.so.conf文件中添加libhello.so的路径
然后执行:ldconfig命令
此时执行可执行文件test就能成功了。