Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1440612
  • 博文数量: 241
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 2253
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-11 22:27
个人简介

--

文章分类

全部博文(241)

文章存档

2021年(3)

2019年(6)

2018年(1)

2017年(9)

2016年(21)

2015年(50)

2014年(125)

2013年(26)

我的朋友

分类: LINUX

2015-04-04 17:06:21

1.为什么使用动态链接库?     
为了使程序方便扩展,具备通用性,可以采用插件形式。采用异步事件驱动模型,保证主程序逻辑不变,将各个业务已动态链接库的形式加载进来,这就是所谓的插件。linux提供了加载和处理动态链接库的系统调用,非常方便。

2.Linux动态链接库的API
Linux提供了一套API来动态装载库。下面列出了这些API:

- dlopen,打开一个库,并为使用该库做些准备。
- dlsym,在打开的库中查找符号的值。
- dlclose,关闭库。
- dlerror,返回一个描述最后一次调用dlopen、dlsym,或dlclose的错误信息的字符串。

dlopen

基本定义

功能:打开一个动态链接库 
  包含头文件: 
  #include  
  函数定义: 
  void * dlopen( const char * pathname, int mode ); 
  函数描述: 
  在dlopen的()函数以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程。使用dlclose()来卸载打开的库。 
  mode:分为这两种 
  RTLD_LAZY 暂缓决定,等有需要时再解出符号 
  RTLD_NOW 立即决定,返回前解除所有未决定的符号。 
  RTLD_LOCAL 
  RTLD_GLOBAL 允许导出符号 
  RTLD_GROUP 
  RTLD_WORLD 

  返回值
  打开错误返回NULL 
  成功,返回库引用 
  编译时候要加入 -ldl (指定dl

dlsym()

 功能:

根据动态链接库操作句柄与符号,返回符号对应的地址。
包含头文件:
#include
函数定义:
void*dlsym(void* handle,const char* symbol)
函数描述:
dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的地址。使用这个函数不但可以获取函数地址,也可以获取变量地址。
handle是由打开后返回的,symbol就是要求获取的函数或的名称。

dlclose()

 

dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。
 
上述都是摘抄,总结为链接的时候需要用到dl库,编译的时候需要加上dlfcn.h头文件。才能保证编译不会报错。

3.使用举例
编译动态链接库
gcc -fPIC -shared caculate.c -o libMyCalFunc.so 

点击(此处)折叠或打开

  1. #include <stdio.h>

  2. int add(int a, int b)
  3. {
  4.         return (a + b);
  5. }

  6. int sub(int a, int b)
  7. {
  8.         return (a - b);
  9. }

  10. int mul(int a, int b)
  11. {
  12.         return (a * b);
  13. }

  14. int div(int a, int b)
  15. {
  16.         return (a / b);
  17. }

主函数连接使用:

gcc -rdynamic -o main main.c -ldl

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <dlfcn.h>

  4. const char LIB_PATH[50] = "./libMyCal.so";

  5. typedef int (* pCalFunc)(int, int);
  6. void main()
  7. {
  8.         pCalFunc pFunc = NULL;
  9.         void *handle = NULL;
  10.         char* error = NULL;
  11.         
  12.         handle = dlopen(LIB_PATH, RTLD_LAZY);
  13.         if (handle == NULL)
  14.         {
  15.                 fprintf(stderr,"%s\n", dlerror());
  16.                 return;
  17.         }
  18.         dlerror();
  19.         
  20.         *(void* *)&pFunc = dlsym(handle, "add");
  21.         if ((error=dlerror()) != NULL)
  22.         {
  23.                 fprintf(stderr,"%s\n",error);
  24.                 return ;
  25.         }
  26.         
  27.         printf("add: %d\n",(*pFunc)(2,8));
  28.         
            dlclose(handle);
  29. }
执行结果:
./main 
add: 10

阅读(2268) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~