linux中的显式运行时链接---dlopen、dlsym、dlerror、dlclose搞起

来源:互联网 发布:java struct 编辑:程序博客网 时间:2024/05/22 14:00

        之前, 我们在linux下制作过动态库, 并卖过。 当时我们采用的是隐式链接, 也就是说, 在代码中, 我们不用去关如何打开动态库、如何链接(这些活都交给了链接器), 只需要管如何调用就行。  隐式链接的动态库被进程加载到内存后, 就一直站着这个坑, 直到进程终结。 费时费力, 浪费地盘, 而且不灵活。

       于是, 一种动态加载(程序中指定加载)的方式就出现了, 这就是我们今天要说的显式运行时加载, 这个加载、卸载过程受程序员本身控制(而非链接器), 所以有了更大的自由度。 对于一些需要长时间运行的程序(如后台服务), 利用显式运行时链接链接就很有好处了, 非常便于升级so库。

       废话少说, 直接撸起:

       taoge_add.c的代码为:

int add(int x, int y){    return x + y;}
       main.c的代码为:

#include <stdio.h>#include <stdlib.h>#include <dlfcn.h>typedef int (*pFUN)(int, int); // 函数指针类型int main(){    void *pHandle = NULL;    char *pError = NULL;    pFUN pfun = NULL;    pHandle = dlopen("./libtaoge.so", RTLD_NOW); // 打开动态链接库    if (NULL == pHandle) {    printf("dlopen:%s\n", dlerror());    return -1;    }    pfun = dlsym(pHandle, "add");    if ((pError = dlerror()) != NULL)  // 这里不要直接用pfun和NULL比较{    printf("dlsym:%s\n", pError);    return -2;    }    printf("sum is : %d\n", (*pfun)(1, 2));    dlclose(pHandle);return 0;}

        好, 撸起:

taoge@localhost Desktop> gcc -shared -fPIC taoge_add.c -o libtaoge.sotaoge@localhost Desktop> gcc main.c -o a.out -ldltaoge@localhost Desktop> ./a.out sum is : 3taoge@localhost Desktop> 
       结果OK,  我们看看编译和链接过程: 

       1. 制作动态库libtaoge.so的方法和以前完全一致

       2. 链接的方式不一样了, 以前需要在编译main.c时候指定libtaoge.so库, 现在是执行dl.so库(应为程序中链接的API需要它)。 其实, 本质也是一致的, 就是想办法找到libtaoge.so, 然后链接到它。


       下面, 我们继续看看如果libtaoge.so不存在会怎么办?

taoge@localhost Desktop> gcc -shared -fPIC taoge_add.c -o libtaoge.sotaoge@localhost Desktop> gcc main.c -o a.out -ldltaoge@localhost Desktop> ./a.out sum is : 3taoge@localhost Desktop> rm libtaoge.so taoge@localhost Desktop> ./a.out dlopen:./libtaoge.so: cannot open shared object file: No such file or directory
        这个提示好眼熟偷笑 这也从侧面说明, 在编译截断, 动态库没有被编进a.out,  是运行时动态加载的。



      


0 0