动态库的重复链接
背景
如果现有系统的库有两个层次,底层库和接口库。接口库通过dlopen的方式加载底层库,接口库提供给用户使用。现在需要在用户层调用底层库的接口,应该如何做?
一个解决方案(有问题的)
一个直观地解决方案就是直接给出底层库需要调用的接口的原型,然后直接调用。由于调用接口需要在编译时确定,因此需要显式指定链接库。这种方式的一个问题就是动态库被加载了两次,加载两次的效果通过如下例子可以观察:
例子如下:
/* file: test.c */
int g_value = 1;
/* file: main.c */
#include <dlfcn.h>
#include <unistd.h>
#include <stdio.h>
extern int g_value;
int main()
{
char libname[] = "libtest.so";
g_value = 0;
printf("value=%d, p=%p\n", g_value, &g_value);
void *handle = dlopen(libname, RTLD_NOW);
if (!handle)
{
printf("dlopen error\n");
return -1;
}
int *value = (int*)dlsym(handle, "g_value");
printf("value=%d, p=%p\n", *value, value);
dlclose(handle);
handle = 0;
return 0;
}
# 编译命令
g++ test.c -shared -fPIC -o libtest.so
g++ main.c -L. -ltest -o main.out
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
./main.out
value=0, p=0x5590e7ebe010
value=1, p=0x7f1943211020
显然,这种方式中,两次加载的库的全局变量总共存在两份。这个现象说明,动态库在内存中总共有两份,这可能会引起问题(部分资源是需要单例访问)。
标签:main,handle,重复,value,int,接口,动态,链接,加载 From: https://www.cnblogs.com/amazzzzzing/p/16993429.html