• shared library


    原文

    shared library

    compatible vs incompatible

    compatible library
    函数的工作场景没有变化

    • 所有的函数对全局变量和返回参数产生相同的影响
    • 所有的函数继续返回相同的结果值
    • 提升性能 fix bugs
      没有api 被删除
    • 可以有新的api加入
      export 的结构体没有变化
      违反以上各条的library 都是incompatible

    library verison and naming

    如果新版本的库与老版本的库是兼容的,我们需要修改minor version number
    如果新版本的库与老版本的库是不兼容的,我们需要修改major version number

    real name

    real name 是有库代码的文件的名字
    format: libxxxx.so.major-id.minor-id
    major-id : 是不断递增的数字 用来标记不兼容的库
    minor-id: 用来区分在相同major-id下不同的但是兼容的子版本库
    通常情况下,子版本号可以是一个数字或者用点分隔开的两个数字,第一个表示子版本号,第二个表示patch level 或者 revision number

     libdemo.so.1.0.1
    libdemo.so.1.0.2
    libdemo.so.2.0.1
    libreadline.so.4.0
    
    • 1
    • 2
    • 3
    • 4

    soname

    format : libname.so.major-id
    soname 与realname 有相同的major-id 但没有子版本号
    运行时加载只是依赖于主版本号
    soname 是符号链接,指向有最近子版本号的库
    我们可以更改符号链接到最新版本的库
    不同主版本号的库可以共存,可执行程序通过记录他的soname 即可
    sample

    libdemo.so.1        -> libdemo.so.1.0.2
    libdemo.so.2        -> libdemo.so.2.0.1
    libreadline.so.4    -> libreadline.so.4.0
    
    • 1
    • 2
    • 3

    linker name

    format: libname.so
    目标是能够提供一种版本独立的链接命令,它可以自动选择正确版本的库。
    创建符号链接指向realname或者soname
    在这里插入图片描述

    动态加载库

    dlopen api:
    Four key functions: dlopen(), dlerror(), dlsym(), and dlclose().

    /* Usage: dynload lib-path func-name */
    
    #include 
    #include 
    #include 
    
    int
    main(int argc, char *argv[])
    {
        void *libHandle;            /* Handle for shared library */
        void (*funcp)(void);        /* Pointer to function with no args */
        char *err;
    
        if (argc != 3) {            /* Check command line arguments */
            fprintf(stderr, "Usage: %s lib-path func-name\n", argv[0]);
            exit(EXIT_FAILURE);
        } /* if */
    
        /* Load the shared library and get a handle for later use */
    
        libHandle = dlopen(argv[1], RTLD_NOW);
        if (libHandle == NULL) {
            fprintf(stderr, "Error on dlopen: %s\n", dlerror());
            exit(EXIT_FAILURE);
        } /* if */
    
        /* Get a pointer to named function inside library */
    
        (void) dlerror();           /* Clear dlerror() */
    	
        /* The strange cast below is required by C99, which	forbids 
            assignment between a function pointer and void * */
    	
        *(void **) (&funcp) = dlsym(libHandle, argv[2]);
        
        err = dlerror();
        if (err != NULL) {  /* Non-NULL from dlerror() means we got error */
            fprintf(stderr, "Error on dlsym: %s\n", err);
            exit(EXIT_FAILURE);
        } /* if */
    
        /* If the function address is non-NULL try calling it */
    
        if (funcp == NULL)
            printf("%s is NULL\n", argv[2]);
        else
            (*funcp)();
    
        /* And close the library */
    
        dlclose(libHandle);
    
        exit(EXIT_SUCCESS);
    } /* main */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
  • 相关阅读:
    django项目实战基于Python实现的衣物捐赠系统
    Java时间复杂度和空间复杂度(详解)
    结构型设计模式——外观模式
    Servlet篇 —— 我的第一个Servlet程序
    elementUI循环动态生成表格内容
    第2次作业练习题(第三章 指令系统)
    面向防疫的智能导诊机器人关键技术及应用
    四种强制类型转换
    【软考 系统架构设计师】计算机网络③ 网络存储技术
    WordPress 6.1 “Misha“
  • 原文地址:https://blog.csdn.net/dongkun152/article/details/131756657