Linux程序运行中加载动态库

Linux程序运行中加载动态库

Linux C/C++程序通常是在编译的时候链接依赖的动态库.
同时,也提供一种在运行时加载动态库的方法.(具体man dlopen中有说明和使用范例.)

应用的场景,暂时想到是 :

  • 类似插件.不用更新整个应用程序,通过更新或新增动态库,实现更新或者增加功能.

    在之前的一个开源的项目streamtunner中就有使用这种. 用户可以更新或自行新增网络源.

  • 方便更新和调试

    由不同开发人员实现统一接口,按照动态库的形式输出. 调用者可以在不修改源码同时不用重新编译主程序的情况下,调用接口实现.

针对第二种场景, 下面是一个示例.(main中是拷贝自man dlopen中的范例.)
Makefile

all:
    @#动态库编译.
    gcc -Wall -c -o sort_a.o sort_a.c
    gcc -shared -fPIC -o libsorta.so sort_a.o
    @#可执行程序编译.
    gcc -Wall -o sortcall main.c -ldl

sort_a.c

int sort_a(int* a, int n)
{
    int ret = 0;

    int i;
    int j;
    int tmp;

    for(i=0; i<n; i++) {
        for(j=i+1; j<n; j++) {
            if(a[i] > a[j]) {
                tmp = a[i];
                a[i] = a[j];
                a[j] = tmp;
            }   
        }   
    }   

    return ret;
}

main.c

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


int main(int argc, char **argv)
{
    void *handle;
    int (*sort)(int*, int);
    char *error;

    if(2 != argc) {
        fprintf(stderr, "%s\n", "usage : sortcall filepath.");
        exit(EXIT_FAILURE);
    }   

    handle = dlopen(argv[1], RTLD_LAZY);
    if (!handle) {
        fprintf(stderr, "%s\n", dlerror());
        exit(EXIT_FAILURE);
    }   

    dlerror();    /* Clear any existing error */

    /* Writing: cosine = (double (*)(double)) dlsym(handle, "cos");
    would seem more natural, but the C99 standard leaves
    casting from "void *" to a function pointer undefined.
    The assignment used below is the POSIX.1-2003 (Technical
    Corrigendum 1) workaround; see the Rationale for the
    POSIX specification of dlsym(). */

    *(void **) (&sort) = dlsym(handle, "sort_a");

    if ((error = dlerror()) != NULL)  {
        fprintf(stderr, "%s\n", error);
        exit(EXIT_FAILURE);
    }   

    int a[6] = {1, 4, 6, 3, 2, 1}; 

    (*sort)(a, 6); 

    int i;
    for(i=0; i<6; i++) {
        printf("%d ", a[i]);
    }   
    printf("\n");

    dlclose(handle);
    exit(EXIT_SUCCESS);
}

执行 : ./sortcall libsorta.so

其他开发人员可以实现不同的排序方法后, 以动态库xxx.so的形式输出.
即可调用 ./sortcall xxx.so以测试不同的排序实现.

以上,谢谢.

  • 0
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

Freeze_Z

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值