之前, 我们在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
这个提示好眼熟
