Linux下动态加载库

来源:互联网 发布:mac用迅雷下不了东西? 编辑:程序博客网 时间:2024/05/16 05:24

Linux下动态加载库

七月 9th, 2011 发表评论阅读评论

以前看到过windows下加载动态库的例子,Linux下没有特别关注过。动态加载库有很多好处,比如通过读取配置文件,按照配置信息来为指定类型或指定目录下的数据使用指定的动态库方法,既实现了程序的松耦合,也方便扩展。

在Linux下动态加载库要使用到dl库。使用的方法记录如下:

1、先生成一个动态库libtest.so

   1:  /* test.c */
   2:  #include <stdio.h>
   3:  int add(int a, int b)
   4:  {
   5:      printf("call add method\n");
   6:      return a+b;
   7:  }
   8:  void sayHello(char *s)
   9:  {
  10:      printf("hello, %s\n", s);
  11:  }

编译库: gcc –fPIC –shared –o libtest.so test.c

2、程序动态加载库

   1:  /* main.c */
   2:  #include <unistd.h>
   3:  #include <stdio.h>
   4:  #include <stdlib.h>
   5:  #include <sys/types.h>
   6:  #incllude <dlfcn.h>  //dl库使用到的方法
   7:  #include <assert.h>
   8:   
   9:  int main()
  10:  {
  11:      void *handler = dlopen("./libtest.so", RTLD_NOW);
  12:      assert(handler != NULL);
  13:      int (*method1)(int, int) = dlsym(handler, "add");
  14:      assert(method1 != NULL);
  15:      void (*method2)(char *) = dlsym(handler, "sayHello");
  16:      assert(method2 != NULL);
  17:      printf("%d+%d=%d\n", 1, 2, (*method1)(1,2));
  18:      printf("%s\n", (*method2)("world"));
  19:      dlclose(handler);
  20:      return 0;
  21:  }

编译程序:gcc –o main main.c –ldl

将libtest.so置于main同目录,执行./main,将会看到调用动态库两个方法的结果。

通过使用条件编译,可以分别实现windows和linux下的动态库加载,实现自己的一个程序框架变成了现实。


一般来说,完全使用C编写代码机会很少,c++中调用动态库和c稍有不同,具体体现在下面几点:

1、动态库中的函数定义前需要增加 extern "C" 即上一篇文章中test.c源码的第3行和第8行需要修改为

extern "C" int add(int a, int b)
extern "C" void sayHello(char *s)

然后编译使用 g++ –fPIC –shared –o libtest.so test.cpp

2、获取动态库函数指针处需要进行类型转换,即main.c源码第13行和第15行需要修改为

int (*method1)(int, int) = (int (*)(int, int))dlsym(handler, "add");
void (*method2)(char *s) = (void (*)(char *))dlsym(handler, "sayHello");
 
然后编译 g++ –ldl –o main main.cpp
 
归纳一下:
1、动态库被调用函数需要使用extern "C"修饰符;
2、动态库编译时需要使用-fPIC编译选项;
3、调用动态库,需要包括 dlfcn.h头文件;
4、使用dlopen、dlsym和dlclose、dlerror函数装载和调用动态库及其方法、卸载动态库以及获取错误信息。