基于unix的系统中等效的延迟加载是什么。
我有一个代码foo.cpp
,在用gcc编译时,我将它链接到共享对象(共有三个.so文件。)。每个.so文件都有不同的选项。
./foo -v
需要libversion.so
./foo -update
需要libupdate.so
我需要这些库的符号才能在运行时解析。
即使libupdate.so库不存在, ./foo -v
也不应该中断。
它在Windows中使用延迟加载选项(在dll的属性中)。在unix系统中它的等价物是什么。
-lazy
选项在UNIX中是否也会这样做?如果是这样,在哪里包含此选项:在makefile中或使用链接器ld?
答案 0 :(得分:3)
请参阅系统中有关dlopen()的参考。您可以在运行时而不是在链接时手动打开库并解析外部符号。
挖出一个例子:
int main(int argc, char **argv) {
void *handle=NULL;
double (*myfunc)(double);
char *err=NULL;
handle = dlopen ("/lib/libm.so.1", RTLD_LAZY);
if (!handle) {
err=dlerror();
perror(err);
exit(1);
}
myfunc = dlsym(handle, "sin");
if ((err = dlerror()) != NULL) {
perror(err);
exit(1);
}
printf("sin of 1 is:%f\n", (*myfunc)(1.));
dlclose(handle);
return 0;
}
答案 1 :(得分:1)
我知道已经8年了但仍然......
GNU系统上不支持延迟加载,但您可以通过创建一个小的静态存根来自己模拟它,该存根提供所有必要的符号,并在第一次调用时提供dlopen
实际实现(甚至在程序启动时) )。这样的存根可以手工编写,由项目特定的脚本或Implib.so tool生成:
# Replace
$ gcc -o foo foo.c -lversion
# with
$ implib-gen.py libversion.so
$ gcc -o foo foo.c libversion.tramp.S libversion.init.c