linux共享库的使用

     前面我介绍了*.so文件的编译和生成。

     但对绝大多数的程序员,绝大多数时候来讲,我们更多的使用现有的共享库。例如上一节我们做好的:libtest.so。

     共享库的使用有2钟方式:

     (1)一种是像静态库那样在编译时进行链接。即把动态链接库里的函数链接到我们现有程序。

       例如,我们写了一个程序,并且要使用到我们编译生成的libtest.so:

我们在代码中要做的,只需要把共享库头文件包括进来:

     Main.c:

#include "so_test.h"                   /*把库的头文件include进来*/
int main()

{
  MyTestFunction();/*使用了动态链接库里的MyTestFunction函数*/
  return 0;
}


(2)在运行时动态加载,实现类似插件的功能。要实现共享库的动态加载,必须用到系统提供的一组函数dlopen,dlsym,dlclose等。

1.dlopen 打开共享库
该函数搜索指定的共享库文件,如果该共享库还没有被加载到共享内存中,则加载到共享内存中,并且共享库的总引用数加一;
void *dlopen(const char *path, int mode);
其中,path是共享库的名称,mode是对标示符引用的处理方式,值可为RTLD_LAZY或RTLD_NOW,两者的区别是如果共享库中包含了另外一个共享库的引用,对于RTLD_LAZY模式会运行到引用那里时才会加载另一个共享库,而RTLD_LAZY模式则是加载共享库的时候就会加载另一个共享库。为了提高效率,一般用RTLD_LAZY模式。
该函数返回指向已打开的共享库的句柄指针,供其他函数使用,如果返回NULL表示调用失败。

2.dlsym 获得应用指针
该函数用来获得一个指向函数或数据结构的指针;
void * dlsym(void *handle, const char *symbol);
其中,handle是dlopen函数返回的句柄指针,symbol是函数名或外部数据结构名;
该函数返回指向要获取的函数或数据结构的指针(是(void *)类型,还要经过强制类型转换),如果返回NULL表示该函数或数据结构不存在。

3.dlclose 关闭共享库
该函数关闭已打开的共享库,将共享库的总引用数减一,如果总引用数降为0,则系统会从内存中卸载该共享库并释放资源。
int dlclose(void *handle);
其中,handle是dlopen函数返回的句柄指针;
该函数返回共享库的剩余的总引用数。

4.dlerror 返回错误信息
该函数用来获得dlopen和dlsym调用失败时的具体的错误信息;
const char * dlerror(void);
该函数返回一个字符串指针,指向产生的最后一个错误。

5._init 初始化函数
当dlopen第一次加载共享库时,如果共享库中存在_init()函数,则会自动调用该函数;
void _init(void);

6._fint 析构函数
当dlclose卸载共享库时,如果共享库中存在_fnit()函数,则会自动调用该函数;
void _fnit(void);


使用举例:
mytest.c

  1. #include <stdio.h>;
  2. #include <dlfcn.h>;

  3. int main(void)
  4. {
  5.     void *dlh;
  6.     int (*func)(void);
  7.    
  8.     dlh = dlopen("libtest.so", RTLD_LAZY);
  9.     if (dlh == NULL)
  10.     {
  11.         printf("Load libtest.so fail, %s\n", dlerror());
  12.         exit(1);
  13.     }
  14.     func = (int (*)(void))dlsym(dlh, "MyTestFunction");/*MyTestFunction是在libtest.so里提供和实现的*/
  15.     if (func == NULL)
  16.     {
  17.         printf("Load symbol myfunction fail, %s\n", dlerror());
  18.         exit(2);
  19.     }
  20.     func(); /*使用动态共享库里的函数*/
  21.     fclose(dlh);
  22.     exit(0);
  23. }
复制代码


按如下编译:
对于SCO UNIX: cc -o mytest mytest.c -lc -dy -ldl
对于AIX:      cc -o mytest mytest.c -lc
对于Linux:    gcc  -o mytest mytest.c -lc -ldl

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值