之前, 我们在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;
}

        好, 撸起(注意,如下编译出a.out的过程,不需要链接libtest.so库):

taoge@localhost Desktop> gcc -shared -fPIC taoge_add.c -o libtaoge.so
taoge@localhost Desktop> gcc main.c -o a.out -ldl
taoge@localhost Desktop> ./a.out 
sum is : 3
taoge@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.so
taoge@localhost Desktop> gcc main.c -o a.out -ldl
taoge@localhost Desktop> ./a.out 
sum is : 3
taoge@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,  是运行时动态加载的。



      



本文转载:CSDN博客