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

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

linker name

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

动态加载库

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

/* Usage: dynload lib-path func-name */

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

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 */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值