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

    本定义


      功能:打开一个动态链接库
      包含头文件:
      #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选项 ,以产生可调用动态链接库的执行代码。


    [cpp] view plaincopyprint?
    01.EXAMPLE 
    02.Load the math library, and print the cosine of 2.0: #include <stdio.h> 
    03.#include <dlfcn.h>  
    04. 
    05.int main(int argc, char **argv) { 
    06.    void *handle; 
    07.    double (*cosine)(double); 
    08.    char *error; 
    09. 
    10.    handle = dlopen ("libm.so", RTLD_LAZY); 
    11.    if (!handle) { 
    12.        fprintf (stderr, "%s ", dlerror()); 
    13.        exit(1); 
    14.    } 
    15. 
    16.    cosine = dlsym(handle, "cos"); 
    17.    if ((error = dlerror()) != NULL)  { 
    18.        fprintf (stderr, "%s ", error); 
    19.        exit(1); 
    20.    } 
    21. 
    22.    printf ("%f ", (*cosine)(2.0)); 
    23.    dlclose(handle); 
    24.    return 0; 
    25.} 
    26.#include <stdio.h>  
    27.#include <dlfcn.h>  
    28. 
    29.int main(int argc, char **argv) { 
    30.    void *handle; 
    31.    double (*cosine)(double); 
    32.    char *error; 
    33. 
    34.    handle = dlopen ("libm.so", RTLD_LAZY); 
    35.    if (!handle) { 
    36.        fprintf (stderr, "%s ", dlerror()); 
    37.        exit(1); 
    38.    } 
    39. 
    40.    cosine = dlsym(handle, "cos"); 
    41.    if ((error = dlerror()) != NULL)  { 
    42.        fprintf (stderr, "%s ", error); 
    43.        exit(1); 
    44.    } 
    45. 
    46.    printf ("%f ", (*cosine)(2.0)); 
    47.    dlclose(handle); 
    48.    return 0; 
    49.} 
    50. 
    51. If this program were in a file named "foo.c", you would build the program with the following command:  
    52. 
    53. gcc -rdynamic -o foo foo.c -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;
    }
    #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

  • 相关阅读:
    使用C#实现DHT磁力搜索的BT种子后端管理程序+数据库设计(开源)
    便携版WinSCP在命令行下同步文件夹
    ffmpeg (ffprobe)分析文件关键帧时间点
    sqlite删除数据或者表后,回收数据库文件大小
    ubuntu 20.04下 freeswitch 配合 fail2ban 防恶意访问
    ffmpeg使用nvenc编码的结论记录
    PC版跑跑卡丁车 故事模式 亚瑟传说章节 卡美洛庆典 2阶段 心灵之眼 攻略
    There was an error loading or playing the video
    Nvidia RTX Voice 启动报错修复方法
    火狐浏览器 关闭跨域限制
  • 原文地址:https://www.cnblogs.com/skyofbitbit/p/3676384.html
Copyright © 2011-2022 走看看