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 = ;
int b = ;
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 ;
}

编译生产可执行文件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 = ;
int b = ; 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 -;
} 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 ;
}

程序执行结果如下所示: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动态链接库的使用的更多相关文章

  1. Linux动态链接库的创建与使用

    Linux动态链接库的创建与使用1. 介绍     使用GNU的工具我们如何在Linux下创建自己的程序函数库?一个“程序函数库”简单的说就是一个文件包含了一些编译好的代码和数据,这些编译好的代码和数 ...

  2. linux 动态链接库查找方法;查找动态链接库位置; LIBRARY_PATH 和 LD_LIBRARY_PATH 的区别;LD_LIBRARY_PATH and LD_RUN_PATH的区别;

    今天配置之前项目的时候,发现有些动态链接库变了,想看看现在应用在使用哪些动态链接库的时候,进一步查了点资料: 下面针对linux动态链接库查找方法和动态链接库位置配置的过程进行记录: LIBRARY_ ...

  3. Linux 动态链接库

    如何使用动态链接库 Linux下打开使用动态链接库需要三步(实际上和windows下基本一样):1.加载动态链接库,通过调用库函数dlopen()获得链接库的句柄,对应于windows下的 AfxLo ...

  4. Linux 动态链接库学习笔记

    参考资料: http://www.linuxidc.com/Linux/2012-01/50739.htm http://www.yolinux.com/TUTORIALS/LibraryArchiv ...

  5. linux动态链接库---一篇讲尽

    一般我们在Linux下执行某些外部程序的时候可能会提示找不到共享库的错误, 比如: tmux: error while loading shared libraries: libevent-1.4.s ...

  6. Linux动态链接库的生成和使用

    目录 1. 编写C程序 2. 编译动态链接库 3. 使用共享库 4. 执行程序 5. 参考资料 1. 编写C程序 比如编写myfunc.c文件,里面包含两个函数,一个是say_hello,另一个是ca ...

  7. Linux 动态链接库 - dll劫持

    如何使用动态链接库 Linux下打开使用动态链接库需要三步(实际上和windows下基本一样):1.加载动态链接库,通过调用库函数dlopen()获得链接库的句柄,对应于windows下的 AfxLo ...

  8. Linux 动态链接库(.so)的使用

    1. 背景 库:就是已经编写好的,后续可以直接使用的代码. c++静态库:会合入到最终生成的程序,使得结果文件比较大.优点是不再有任何依赖. c++动态库:动态库,一个文件可以多个代码同时使用内存中只 ...

  9. linux动态链接库

    前言 静态链接库会编译进可执行文件,并被加载到内存,会造成空间浪费 静态链接库对程序的更新.部署.发布带来麻烦.如果静态库更新了,使用它的应用程序都需要重新编译.发布给用户(对于玩家来说,可能是一个很 ...

随机推荐

  1. Linux 网络流量实时监控工具之ntopng详解

    大纲一.前言二.ntopng 简介三.ntopng 功能说明 四.ntopng 安装详解五.ntopng 配置详解 六.ntopng 使用详解注,操作系统 CentOS 5.5 X86_64,软件版本 ...

  2. httpwatch抓包工具的使用方法

    火狐浏览器下有著名的httpfox,而HttpWatch则是IE下强大的网页数据分析工具.这个工具到底有哪些具体功能呢?这个我就不再赘述了,百度百科上列的很全面,但也比较抽象.我只想说我曾经用这个工具 ...

  3. HDU 4739 Zhuge Liang's Mines (2013杭州网络赛1002题)

    Zhuge Liang's Mines Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  4. dotNetSpider 手记

    准备工作: 从github上download工程. 安装VS2017. 安装 .net core 2.0. 编译通过. 基础架构: 调度器 Scheduler 从根site开始,向 Downloade ...

  5. gitblit.cmd运行自动关闭

    前几天运行gitblit.cmd一直正常,今天运行gitblit.cmd,几秒钟后命令行窗口就自动关闭了,导致无法启动gitblit服务器,查看日志如下: 刚开始以为是防火墙问题,在防火墙中添加了程序 ...

  6. 北大 ACM 分类 汇总

    1.搜索 //回溯 2.DP(动态规划) 3.贪心 北大ACM题分类2009-01-27 1 4.图论 //Dijkstra.最小生成树.网络流 5.数论 //解模线性方程 6.计算几何 //凸壳.同 ...

  7. TIDB VS COCKROACHEB

    分布式事务 要支持分布式事务,首先要解决的就是分布式系统时间的问题,也就是我们用什么来标识不同事务的顺序.通常有几种做法: TrueTime,TrueTime 是 Google Spanner 使用的 ...

  8. .Net Discovery 系列之五--深入浅出.Net实时编译机制(上)

    欢迎阅读“.Net Discovery 系列”文章,本文将分上.下两部分为大家讲解.Net JIT方面的知识,敬请雅正. JIT(Just In Time简称JIT)是.Net边运行边编译的一种机制, ...

  9. Linux 内核网络协议栈 ------sk_buff 结构体 以及 完全解释 (2.6.16)

    转自:http://blog.csdn.net/shanshanpt/article/details/21024465 在2.6.24之后这个结构体有了较大的变化,此处先说一说2.6.16版本的sk_ ...

  10. git合并的时候,冲突问题Merging is not possible because you have unmerged files

    在做项目工作的时候,同事修改了代码一个cpp代码,我同样也修改了代码,两人代码冲突了,提交之后,他代码git自动合并,并提示: [master| MERGEING]$ git merge my_new ...