Linux动态链接库的使用
1、前言
在实际开发过程中,各个模块之间会涉及到一些通用的功能,比如读写文件,查找、排序。为了减少代码的冗余,提高代码的质量,可以将这些通用的部分提取出来,做出公共的模块库。通过动态链接库可以实现多个模块之间共享公共的函数。之前看《程序员的自我修养》中讲到程序的链接和装入过程,这些玩意都是底层的,对于理解程序的编译过程有好处。http://www.ibm.com/developerworks/cn/linux/l-dynlink/博文介绍了程序的链接和装入过程。本文重点在于应用,如何编写和使用动态链接库,后续使用动态链接库实现一个插件程序。
2、动态链接库生产
动态链接库与普通的程序相比而言,没有main函数,是一系列函数的实现。通过shared和fPIC编译参数生产so动态链接库文件。程序在调用库函数时,只需要连接上这个库即可。例如下面实现一个简单的整数四则运输的动态链接库,定义的caculate.h和caculate.c两个文件,生产libcac.so动态链接库。
程序代码如下:
![复制代码](http://common.cnblogs.com/images/copycode.gif)
/*caculate.h*/ #ifndef CACULATE_HEAD_ #define CACULATE_HEAD_ int add(int a, int b); int sub(int a, int b); int div(int a, int b); int mul(int a, int b); #endif
![复制代码](http://common.cnblogs.com/images/copycode.gif)
![复制代码](http://common.cnblogs.com/images/copycode.gif)
/*caculate.c文件*/
#include "caculate.h" //求两个数的和 int add(int a, int b) return (a + b); int sub(int a, int b) return (a - b); int div(int a, int b) return (int)(a / b); int mul(int a, int b) return (a * b); }
![复制代码](http://common.cnblogs.com/images/copycode.gif)
编译生产libcac.so文件如下: gcc -shared -fPIC caculate.c -o libcac.so
编写一个测试程序调用此动态链接库的函数,程序如下所示:
![复制代码](http://common.cnblogs.com/images/copycode.gif)
#include stdio.h #include "caculate.h" int main() int a = 20; int b = 10; printf("%d + %d = %d\n", a, b, add(a, b)); printf("%d - %d = %d\n", a, b, sub(a, b)); printf("%d / %d = %d\n", a, b, div(a, b)); printf("%d * %d = %d\n", a, b, mul(a, b)); return 0; }
![复制代码](http://common.cnblogs.com/images/copycode.gif)
编译生产可执行文件main如下:gcc main.c -o main -L ./ -lcac (其中-L指明动态链接库的路径,-l后是链接库的名称,省略lib)
程序执行结果如下所示:
3、获取动态链接库的函数
linux提供dlopen、dlsym、dlerror和dlcolose函数获取动态链接库的函数。通过这个四个函数可以实现一个插件程序,方便程序的扩展和维护。函数格式如下所示:
![复制代码](http://common.cnblogs.com/images/copycode.gif)
#include dlfcn.h void *dlopen(const char *filename, int flag); char *dlerror(void); void *dlsym(void *handle, const char *symbol); int dlclose(void *handle); Link with -ldl.
![复制代码](http://common.cnblogs.com/images/copycode.gif)
dlopen()是一个强大的库函数。该函数将打开一个新库,并把它装入内存。该函数主要用来加载库中的符号,这些符号在编译的时候是不知道的。写个测试程序调用上面生产libcac.so库如下所示:
![复制代码](http://common.cnblogs.com/images/copycode.gif)
#include stdio.h #include dlfcn.h #define DLL_FILE_NAME "libcac.so" int main() void *handle; int (*func)(int, int); char *error; int a = 30; int b = 5; handle = dlopen(DLL_FILE_NAME, RTLD_NOW); if (handle == NULL) fprintf(stderr, "Failed to open libaray %s error:%s\n", DLL_FILE_NAME, dlerror()); return -1; func = dlsym(handle, "add"); printf("%d + %d = %d\n", a, b, func(a, b)); func = dlsym(handle, "sub"); printf("%d + %d = %d\n", a, b, func(a, b)); func = dlsym(handle, "div"); printf("%d + %d = %d\n", a, b, func(a, b)); func = dlsym(handle, "mul"); printf("%d + %d = %d\n", a, b, func(a, b)); dlclose(handle); return 0; }
![复制代码](http://common.cnblogs.com/images/copycode.gif)
程序执行结果如下所示:gcc call_main.c -o call_main -ldl
Linux 动态链接库(.so)的使用 1. 背景 库:就是已经编写好的,后续可以直接使用的代码。 c++静态库:会合入到最终生成的程序,使得结果文件比较大。优点是不再有任何依赖。 c++动态库:动态库,一个文件可以多个代码同时使用内存中只有一份,节省内存,可以随主代码一起编译。
linux找不到动态链接库 .so文件的解决方法(转自:http://www.cnblogs.com/xudong-bupt/p/3698294.html) linux找不到动态链接库 .so文件的解决方法 如果使用自己手动生成的动态链接库.so文件,但是这个.so文件,没有加入库文件搜索路劲中,程序运行时可能会出现找不到动态链接库的情形。 可以通过ldd命名来查看可执行文件依赖的动态链接库,如下(其中D为可执行程序): 其中的libjson_linux-gcc-4.6_libmt.so cannot found。 解决这个问题: (1)在
linux下查看动态链接库so文件的依赖的相关组建 我们很多c程序在windows下是以dll形式展现的,在linux则是以so 形式展现的。 windows一般不会因为编译dll文件的编译器版本不同而出先dll文件不能执行。 但是linux下,不同版本内核的linux下编译的c程序,在其他版本的linux下就容易出现无法执行的问题。
linux下查看动态链接库依赖关系的命令 x86: ldd *.so arm: arm-linux-readelf -d *.so 实际例子: 以项目中用到的库librtsp.so分析: lijun@ubuntu:~/workspace$ arm-hisiv100nptl- linux下查看动态链接库依赖关系的命令 x86:ldd *.so arm:arm-linux-readelf -d *.so 实际例子:以项目中用到的库librtsp.so分析:lijun@ubuntu:~/workspace$ arm-hisiv100nptl-linux-ld -d librtsp.
制作 ar -cr libxxx.a xxx1.o xxx2.o xxx3.o ... 编译 gcc main.c -l xxx [-L 库路径] (如果不加-L则在标准库路径下查找) 运行 ./a.out
LINUX系统中动态链接库的创建与使用 大家都知道,在WINDOWS系统中有很多的动态链接库(以.DLL为后缀的文件,DLL即Dynamic Link Library)。这种动态链接库,和静态函数库不同,它里面的函数并不是执行程序本身的一部分,而是根据执行程序需要按需装入,同时其执行代码可在多个执行程序间共享,节省了空间,提高了效率,具备很高的灵活性,得到越来越多程序员和用户的青睐。
相关文章
- 用Linux做系统盘:开启捷径之旅(linux做系统盘)
- 使用Linux文件名通配符管理文件(linux文件名通配符)
- Linux在线添加硬盘的步骤指南(linux在线添加硬盘)
- 共同使用Linux与Win7联合部署:构建双系统共融世界(linux安装与win7)
- 发行版最适宜编程者的Linux发行版(适合编程的linux)
- 探索Linux系统启动时的服务(查看linux启动的服务)
- 如何使用硬盘安装Linux操作系统(如何硬盘安装linux)
- Linux搭建网络连接测试环境实践(linux连接测试环境)
- 在 Linux 中实现日志监控的命令技巧(linux监控日志命令)
- 开启Linux入侵之门:揭秘端口背后的故事(linux入侵端口)
- 使用Linux虚拟机实现快乐的程序开发体验(好的linux虚拟机)
- Linux的分支:更新更强的系统核心(linux的分支)
- Linux编程:为未来开创技术新纪元(linux编程项目开发)
- Linux 内存文件的使用方法(linux内存文件)
- 使用 Linux 实现内网映射到外网的配置方法(linux内网映射外网)
- 探索Linux:从个人使用者到高手(linux个人使用)
- Linux脚本中使用su命令:简单实用的权限管理方式(linux脚本su)
- Linux多线程实例:简单易懂的实践指南(linux多线程实例)
- 揭秘Linux内存泄露:使用工具检测系统中存在的漏洞(linux内存泄露工具)
- u盘制作Linux启动U盘:简单步骤轻松搞定(u盘制作linux启动)
- 使用 SSH 远程访问 Linux 服务器(远程到linux服务器)
- 探索Linux的裸设备:查看方法(linux查看裸设备)
- 掌握Linux基本使用技巧:常用命令总结(linux常用的基本命令)
- Linux下蓝牙模块的安装与使用(linux蓝牙模块)
- 如何使用Linux检查硬盘坏道的最佳方法(linux检查硬盘坏道)
- 使用Linux搭建我的世界:轻松建立游戏服务器(linux搭建我的世界)
- Linux下日志分析系统架构研究(日志分析系统linux)
- 打造完美家庭服务器,使用Linux操作系统(家庭服务器linux)
- 如何使用Linux系统中的符号(linux $ 怎么用)