动态库与静态库的区别
静态库:linux下的静态库是以xxx.a文件形式存在的。它类似于windows下的xxx.lib文件,在项目编译的时候它会同项目一起编译到项目的可执行文件中去,所以编译出来的可执行文件会比较大。并且,如果后期对静态库稍加改动的话,需要重新编译整个项目。
动态库:linux下的动态库是以xxx.so文件形式存在的。它类似于windows下的xxx.dll文件,它是在程序运行过程中动态加载进去的,他比较灵活,后期要改动该动态库的时候,不需要重新编译整个工程,只需要将新编译得到的动态库覆盖原先的即可。
GCC编译生成和使用静态库
1.编写我们需要编译成静态库的C源文件
static_lib_test1.c
#include<stdio.h>
void print1()
{
printf("This is static_lib_test1!\n");
}
static_lib_test2.c
#include<stdio.h>
void print2()
{
printf("This is static_lib_test2!\n");
}
2.使用GCC编译我们的C源文件,获得static_lib_test1.o,static_lib_test2.o文件
root@ubuntu:~/job/libtest# gcc -c static_lib_test*.c
3.使用ar指令编译获得我们需要的xxx.a静态库文件
root@ubuntu:~/job/libtest# ar r libtest.a static_lib_test*.o
ar: creating libtest.a
4.编写我们需要的测试代码
static_main.c
#include<stdio.h>
int main(void)
{
printf("This is main functiondd!\n");
print1();
print2();
return 1;
}
5.链接静态库,编译生成可执行文件,-L指定库文件所在的路径,否则编译器无法找到,-l指定静态库
root@ubuntu:~/job/libtest# gcc -o main static_main.c -L. -ltest
6.然后执行可执行文件,即可看到我们需要的效果,成功调用静态库的内容。
root@ubuntu:~/job/libtest# ./main
This is main functiondd!
This is static_lib_test1!
This is static_lib_test2!
GCC编译生成和使用动态库
1.前期操作跟上面没啥区别,我们主要需要了解的是如何生成动态库。
2.使用GCC指令生成动态库文件libxxx.so
root@ubuntu:~/job/libtest# gcc static_lib_test*.c -fPIC -shared -lpthread -o libtest.so
其中-shared参数是指明编译生成静态库;
-fPIC 表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的;
3.最后编译运行测试程序即可。
root@ubuntu:~/job/libtest# gcc -o main static_main.c -L. -ltest
root@ubuntu:~/job/libtest# ./main
This is main functiondd!
This is static_lib_test1!
This is static_lib_test2!
注意:此时直接编译可能会出现error while loading shared libraries: libXXX.so: cannot open shared object file: No such file or directory的错误,说的是找不到我们自己的链接库,这又几种解决方案:
(1)设置环境变量,将我们的链接库所在的目录添加进LD_LIBRARY_PATH环境变量中:export LD_LIBRARY_PATH=/root/job/socket_lib/:$LD_LIBRARY_PATH
(2)编辑/etc/ld.so.config文件,将我们的库文件目录添加进去,然后执行ldconfig进行更新ld.so.cache即可。
(3)在/etc/ld.so.conf.d目录下新建一个xxx.conf文件,将库文件所在目录添加进去,执行ldconfig即可。