zoukankan      html  css  js  c++  java
  • LINUX下动态链接库的使用-dlopen dlsym dlclose dlerror(转)

    dlopen

    基本定义

      功能:打开一个动态链接库 
      包含头文件: 
      #include <dlfcn.h> 
      函数定义: 
      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库) 
      例如 
      gcc test.c -o test -ldl
    编辑本段
    使用 dlopen
      dlopen()是一个强大的库函数。该函数将打开一个新库,并把它装入内存。该函数主要用来加载库中的符号,这些符号在编译的时候是不知道的。比如 Apache Web 服务器利用这个函数在运行过程中加载模块,这为它提供了额外的能力。一个配置文件控制了加载模块的过程。这种机制使得在系统中添加或者删除一个模块时,都不需要重新编译了。 
      可以在自己的程序中使用 dlopen()。dlopen() 在 dlfcn.h 中定义,并在 dl 库中实现。它需要两个参数:一个文件名和一个标志。文件名可以是我们学习过的库中的 soname。标志指明是否立刻计算库的依赖性。如果设置为 RTLD_NOW 的话,则立刻计算;如果设置的是 RTLD_LAZY,则在需要的时候才计算。另外,可以指定 RTLD_GLOBAL,它使得那些在以后才加载的库可以获得其中的符号。 

      当库被装入后,可以把 dlopen() 返回的句柄作为给 dlsym() 的第一个参数,以获得符号在库中的地址。使用这个地址,就可以获得库中特定函数的指针,并且调用装载库中的相应函数。

    --------------------------------------------------------------------------------------------------------------------------

    dlsym
       
      dlsym()的函数原型是 
      void* dlsym(void* handle,const char* symbol) 
      该函数在<dlfcn.h>文件中。 
      handle是由dlopen打开动态链接库后返回的指针,symbol就是要求获取的函数的名称,函数返回值是void*,指向函数的地址,供调用使用

    取动态对象地址:
    #include <dlfcn.h>
    void *dlsym(void *pHandle, char *symbol);
    dlsym根据动态链接库操作句柄(pHandle)与符号(symbol),返回符号对应的地址。
    使用这个函数不但可以获取函数地址,也可以获取变量地址。比如,假设在so中
    定义了一个void mytest()函数,那在使用so时先声明一个函数指针
    void (*pMytest)(),然后使用dlsym函数将函数指针pMytest指向mytest函数,
    pMytest = (void (*)())dlsym(pHandle, "mytest");

    --------------------------------------------------------------------------------------------------------------------------

    dlclose
      dlclose() 
      包含头文件: 
      #include <dlfcn.h> 
      函数原型为: 
      int dlclose (void *handle); 
      函数描述: 
       dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。

    --------------------------------------------------------------------------------------------------------------------------

    dlerror
      dlerror() 
      包含头文件: 
      #include <dlfcn.h> 
      函数原型: 
      const char *dlerror(void); 
      函数描述: 
      当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。

    LINUX创建与使用动态链接库并不是一件难事。
      编译函数源程序时选用-shared选项即可创建动态链接库,注意应以.so后缀命名,最好放到公用库目录(如/lib,/usr/lib等)下面,并要写好用户接口文件,以便其它用户共享。
      使用动态链接库,源程序中要包含dlfcn.h头文件,写程序时注意dlopen等函数的正确调用,编译时要采用-rdynamic选项与-ldl选项 ,以产生可调用动态链接库的执行代码。

    EXAMPLE
    Load the math library, and print the cosine of 2.0: 
    #include <stdio.h>
    #include <dlfcn.h>
    
    int main(int argc, char **argv) {
        void *handle;
        double (*cosine)(double);
        char *error;
    
        handle = dlopen ("libm.so", RTLD_LAZY);
        if (!handle) {
            fprintf (stderr, "%s
    ", dlerror());
            exit(1);
        }
    
        cosine = dlsym(handle, "cos");
        if ((error = dlerror()) != NULL)  {
            fprintf (stderr, "%s
    ", error);
            exit(1);
        }
    
        printf ("%f
    ", (*cosine)(2.0));
        dlclose(handle);
        return 0;
    }
    
     If this program were in a file named "foo.c", you would build the program with the following command: 
    
     gcc -rdynamic -o foo foo.c -ldl
  • 相关阅读:
    UVALive 7509 Dome and Steles
    HDU 5884 Sort
    Gym 101194H Great Cells
    HDU 5451 Best Solver
    HDU 5883 The Best Path
    HDU 5875 Function
    卡特兰数
    UVa 11729 Commando War 突击战
    UVa 11292 The Dragon of Loowater 勇者斗恶龙
    Spark Scala Flink版本对应关系
  • 原文地址:https://www.cnblogs.com/qq78292959/p/4002255.html
Copyright © 2011-2022 走看看