在LInux库的创建和使用–静态库中,我们已经知道了库的概念以及静态库的创建和使用方法。接下来,我们就来讨论一下动态库是如何实现的。
动态库的创建和使用
shell下创建和使用
与静态库的创建和使用比较起来,动态库的创建和使用就方便多了,直接在编译函数库源文件时加上-shared选项就可以,这样生成的可执行程序便是动态链接库,从某种意义上来说,动态链接库就是一种可执行程序。
如图:
或者如下图:
注意:引用动态链接库时,必须含有路径,如果只是使用libmylib.so 则必须确保这个库所在目录包含在PATH环境变量中。
调用系统函数使用动态库
#include<dlfcn.h>
1.void *dlopen(const char *filename, int flag)
2.void *dlsym(void *handle, char *symbol)
3.int dlclose(void *handle)
4.const char *dlerror(void)
各函数说明:
dlopen:用于打开指定名字的动态链接库,返回一个句柄
dlsym:根据动态链接库的句柄和函数名,返回函数名对应的函数的地址
dlclose:关闭动态链接库
dlerror:动态链接库的函数执行失败时,dlerror返回出错信息;若执行成功,则返回NULL
参数flag的说明:
- RTLD_LAZY:在dlopen返回之前,对于动态库中存在的未定义的变量(如外部变量,也可以是函数)不执行解析,也就是不解析这个变量的地址
- RTLD_NOW:与RTLD_LAZY相反,但是如果将未定义的变量的地址没有解析出来,那么dlopen将会返回NULL
- RTLD_GLOBAL:使库中被解析出来的变量在随后的其他链接库中也可以使用,全局有效
附一个调用系统函数来使用动态链接库的程序:
int main()
{
void *handle;
char *error;
void (*welcome) ();
if((handle = dlopen("./libmylib.so", RTLD_LAZY)) == NULL) //打开动态链接库并返回一个句柄
{
printf("dlopen error\n");
exit(1);
}
welcome = dlsym(handle, "welcome"); //根据句柄返回对应函数的函数地址
if((error = dlerror()) != NULL)
{
printf("dlsym error\n");
exit(1);
}
welcome();
dlclose(handle);
exit(0);
}
运行结果:
如图,-l dl指明dlopen等函数所在的库。通过在程序中调用系统函数来使用动态链接库时,动态链接库所在的目录必须包含在程序中,如果动态库不在当前目录下,程序运行出错。