当链接相同的库并与dlopen一起使用时,相同的函数(本例中为sqrt)具有不同的内存地址。你能解释一下为什么会这样吗?是否有一些间接?
# cat dl-test.c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <math.h>
#include <inttypes.h>
int main()
{
void *dl, *dl_sqrt;
dl = dlopen("/lib/x86_64-linux-gnu/libm.so.6", RTLD_LAZY);
if (!dl) {
fprintf(stderr, "%s\n", dlerror());
exit(1);
}
dl_sqrt = dlsym(dl,"sqrt");
if (!dl_sqrt) {
fprintf(stderr, "%s\n", dlerror());
exit(1);
}
printf("Address of sqrt %p\n", (void*) sqrt);
printf("Address of (dl)sqrt %p\n", (void*) dl_sqrt);
return 0;
}
#
# gcc dl-test.c -lm -ldl -o dl-test
# ldd dl-test
linux-vdso.so.1 => (0x00007fff9132b000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f4caee90000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f4caec8c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4cae8c1000)
/lib64/ld-linux-x86-64.so.2 (0x0000559a02daa000)
# ./dl-test
Address of sqrt 0x4006d0
Address of (dl)sqrt 0x7fa7ce6f7250
#
答案 0 :(得分:2)
阅读Drepper的(长篇)论文How To Write Shared Libraries并仔细研究ELF格式。见elf(5),objdump(1),ldd(1),readelf(1),ld-linux(8),dlopen(3),dlsym(3)
是否有一些间接?
是,程序链接表,请参阅this。
另请注意dlopen
具有NULL
文件路径(以获取整个程序的句柄)的特殊情况,以及dlopen
的各种标志....