GCC 动态链接库
获取更多嵌入式、Linux学习资料,获取独家嵌入式Linux学习路线地图,欢迎加群:398294860,观看更专业、更系统地嵌入式视频教程,请关注:wanglitao.taobao.com
静态库里实现的函数,可能被多个应用程序调用,那么在链接时,被调用的这个函数可能就会多次链接到不同的应用程序中。
比如C标准库的printf函数,可能被一个应用程序调用多次,被不同的应用程序调用,当这些应用程序加载到内存运行时,内存中也就存在多个printf函数代码的副本,太浪费了内存空间。而且,对于应用程序来说,每一个调用的库函数都被链接进来,自身的文件体积也会大增。是可忍孰不可忍,动态链接此时就粉墨登场了。
动态链接跟静态链接相比,具有以下优势
- 库的代码不会链接到应用程序里
- 同一份代码(如printf代码)可以被多个应用程序共享使用
- 大大节省了内存空间
但动态库也有缺点,发布软件时,动态库需要和应用程序一起发布,否则你编译的应用程序到了一个新的平台可能就无法运行。
制作一个动态库
# gcc -shared -fPIC -o libmymath.so add.c sub.c
其中的参数说明:
- -shared :动态库编译,链接动态库
- -fPIC(或fpic) :生成使用相对地址无关的目标代码
- -Ldir :在动态库的搜索路径中增加dir目录
- -lname :链接静态库(libname.a)或动态库(libname.so)的库文件
使用动态链接
将动态链接库拷贝到main.c的同一目录下
# tree
.
├── inc
│ ├── add.h
│ └── sub.h
├── libmymath.so
└── main.c
在编译main.c,链接动态库libmymath.so的时候,直接指定当前目录下的libmymath.so文件:
# gcc main.c ./libmymath.so -I inc/
# ls
a.out inc libmymath.so main.c
在当前目录下运行生成的可执行文件a.out,可以正常运行。将a.out拷贝到其他目录,比如/opt目录下,然后再运行,就会出现以下错误:
root@ubuntu:/opt# ls
a.out
root@ubuntu:/opt# ./a.out
./a.out: error while loading shared libraries: ./libmymath.so: cannot open shared object file: No such file or directory
我们需要将对应的libmymath.so文件拷贝到a.out的同一目录下,然后a.out才能正常运行。
Linux的动态链接库一般都放在/lib官方默认目录下。如果想让a.out放在任何路径下都可以运行,我们可以把libmymath.so动态库拷贝到/lib下,然后在编译应用程序时,通过-L参数指定动态链接库的搜索路径。编译生成的a.out在运行时,就会到指定的/lib目录下去加载动态库libmyamth.so:
# cp libmymath.so /lib
# tree
.
├── inc
│ ├── add.h
│ └── sub.h
├── libmymath.so
└── main.c
# gcc main.c -L/lib -lmymath -I inc
# tree
.
├── a.out
├── inc
│ ├── add.h
│ └── sub.h
├── libmymath.so
└── main.c
将生成的a.out拷贝到系统的任何目录下,你会发现,都可以正常运行。
《Linux三剑客》视频教程,从零开始快速掌握Linux开发常用的工具:Git、Makefile、vim、autotools、debug,免费赠送C语言视频教程,C语言项目实战:学生成绩管理系统。详情请点击淘宝链接:Linux三剑客