静态库与动态库
一、 链接方式
链接分为两种:静态链接、动态链接
1. 静态链接
含义:由链接器在链接时将库的内容加入到可执行程序中
优点:对运行环境的依赖性较小,具有较好的兼容性
缺点:(1)生成的程序比较大,需要更多的系统资源,在装入内存时会消耗更多的时间
(2)库函数有了更新,必须重新编译应用程序
2. 动态链接
含义:连接器在链接时仅仅建立与所需库函数的之间的链接关系,在程序运行时才将所需资源调入可执行程序,又称运行时拷贝
优点:(1)在需要的时候才会调入对应的资源函数简化程序的升级;
(2)有着较小的程序体积
(3)实现进程之间的资源共享(避免重复拷贝)
缺点:(1)依赖动态库,不能独立运行
(2)动态库依赖版本问题严重
3.举例比较:
使用gcc hello.c–o hello时,系统默认采用动态链接的方式进行编译程序,若想采用静态编译,加入-static参数,如下:可见两者大小差100倍
二、 动态链接库与静态链接库的制作与使用
1. 编写三个文件
2. 静态库制作
静态链链接库在linux中后缀为.a,以lib开头
(1) 制作:由于静态库多个文件,必须先做成.o
gcc -cmylib.c -o mylib.o //编译目标文件
ar rclibmytest.a mylib.o //制作静态库
(2) 静态库的使用:
1) 库函数、头文件均在当前目录下
gccmytest.c -o mytest libmytest.a //库名放在最后
2) 库函数、头文件假设在/opt系统目录
gccmytest.c -o mytest -L/opt-lmytest -I/opt
注意:libmytest.a要写成lmytest,去掉开头的li和末尾的.a
3) 编译程序时
编译程序时,编译器默认会到/lib/和/usr/lib下查找库函数,到/usr/include下查找头文件
将libmytest.a移到/lib或/usr/lib下
mv libmytest.a /lib
将mylib.h移到/usr/include下
mv mylib.h /usr/include
编译:同样去掉li和.a
gccmytest.c -o mytest –lmytest
//编译器会自动到/lib下查找库文件,到/usr/include 下查找头文件
3. 动态库制作
静态链链接库在linux中后缀为.a,以lib开头
(1)制作动态链接库:
gcc -sharedmylib.c -o libmytest.so
(2)动态链接库的使用
1) 库函数、头文件均在当前目录下
gccmytest.c -o mytest libmytest.so
2) 库函数、头文件假设在/opt系统目录
gcc mytest.c -o mytest -L/opt -lmytest -I/opt
3) 编译通过,运行时出错,编译时找到了库函数,但链接时找不到库,执行以下操作,把当前目录加入搜索路径
export LD_LIBRARY_PATH=./:/opt:
4) 若库函数、头文件均在系统路径下编译运行都不会出错
cp libmytest.so/lib
gcc mytest.c –o mytest –lmytest
./mytest
(3)说明:
我们前面的静态库也是放在/lib下,那么连接的到底是动态库还是静态库呢?
当静态库与动态库重名时,系统会优先连接动态库,或者我们可以加入-static指定使用静态库