linux动态链接库的使用
来源:互联网 发布:万通筋骨贴有用吗 知乎 编辑:程序博客网 时间:2024/06/01 08:01
from: http://www.cnblogs.com/Anker/p/3527677.html
Linux动态链接库的使用
1、前言
在实际开发过程中,各个模块之间会涉及到一些通用的功能,比如读写文件,查找、排序。为了减少代码的冗余,提高代码的质量,可以将这些通用的部分提取出来,做出公共的模块库。通过动态链接库可以实现多个模块之间共享公共的函数。之前看《程序员的自我修养》中讲到程序的链接和装入过程,这些玩意都是底层的,对于理解程序的编译过程有好处。http://www.ibm.com/developerworks/cn/linux/l-dynlink/博文介绍了程序的链接和装入过程。本文重点在于应用,如何编写和使用动态链接库,后续使用动态链接库实现一个插件程序。
2、动态链接库生产
动态链接库与普通的程序相比而言,没有main函数,是一系列函数的实现。通过shared和fPIC编译参数生产so动态链接库文件。程序在调用库函数时,只需要连接上这个库即可。例如下面实现一个简单的整数四则运输的动态链接库,定义的caculate.h和caculate.c两个文件,生产libcac.so动态链接库。
程序代码如下:
/*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
/*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);}
编译生产libcac.so文件如下: gcc -shared -fPIC caculate.c -o libcac.so
编写一个测试程序调用此动态链接库的函数,程序如下所示:
#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;}
编译生产可执行文件main如下:gcc main.c -o main -L ./ -lcac (其中-L指明动态链接库的路径,-l后是链接库的名称,省略lib)
程序执行结果如下所示:
3、获取动态链接库的函数
linux提供dlopen、dlsym、dlerror和dlcolose函数获取动态链接库的函数。通过这个四个函数可以实现一个插件程序,方便程序的扩展和维护。函数格式如下所示:
#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.
dlopen()是一个强大的库函数。该函数将打开一个新库,并把它装入内存。该函数主要用来加载库中的符号,这些符号在编译的时候是不知道的。写个测试程序调用上面生产libcac.so库如下所示:
#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;}
程序执行结果如下所示:gcc call_main.c -o call_main -ldl
4、参考网址
http://www.cnblogs.com/xuxm2007/archive/2010/12/08/1900608.html
http://blog.csdn.net/leichelle/article/details/7465763
- LINUX动态链接库的使用
- linux动态链接库的使用
- linux动态链接库的使用
- LINUX下动态链接库的使用
- Linux下动态链接库的使用
- linux 下动态链接库的使用
- Linux动态链接库的使用
- linux动态链接库的使用
- LINUX下动态链接库的使用
- LINUX动态链接库的使用
- linux下动态链接库的使用
- Linux下动态链接库的使用
- Linux下动态链接库的使用
- Linux动态链接库的使用
- Linux动态链接库的使用
- linux动态链接库的使用
- LINUX下动态链接库的使用
- Linux动态链接库的使用
- javaScript输出
- Echarts饼图、柱状图、折线图(pie、bar、line)添加点击事件
- dd
- Looper、Handler、Message三者关系
- ubuntu下代理设置
- linux动态链接库的使用
- android学习--操作http
- 软件开发模式对比(瀑布、迭代、螺旋、敏捷)
- iOS 9音频应用播放音频之第一个ios9音频实例2
- 扑克游牧民Faraz Jaka访谈
- hihiocoder 1255(搜索)(2015ACM/ICPC北京站)
- 哈希表详解
- linux查看文件数
- yii2 Event的使用 1