我想让我的可执行文件“可选地依赖”其他共享对象。因此,如果没有 DSO,它将能够在没有某些符号的情况下运行。
我可以通过调用来实现这一点,dlopen/dlsym
但我必须手动加载每个符号并为它们添加包装器,如下所示:
void *my_lib = dlopen("my_lib.so", RTLD_LAZY);
if (!my_lib) {
// ok, I promise not to touch my_lib symbols
} else {
my_foo_ptr = dlsym(my_lib, "my_foo");
my_bar_ptr = dlsym(my_lib, "my_bar");
}
... my_foo(...) {
assert(my_foo_ptr);
return (*my_foo_ptr)(...);
}
... my_bar(...) {
assert(my_foo_ptr);
return (*my_bar_ptr)(...);
}
这是一个愚蠢的代码,它直接依赖于“my_lib.so”ABI,这意味着每次库更新时我都必须更新它。
我正在寻找某种方法来ld.so
为我做这件事。所以理想是:
void *my_lib = dlopen("my_lib.so", /* bring me all my symbols */);
if (!my_lib) {
// ok, I promise not to touch my_lib symbols
} else {
// ok, I can directly call symbols from my_lib.so
my_foo();
my_bar();
}
但这有两个问题:
1.在应用链接阶段如何处理这些符号?如果我明确链接到 my_lib.so,则应用程序将严格依赖它,因此如果没有 my_lib.so,则无法启动。如果没有,ld
将抱怨未定义的符号。
2. 如何强制dlopen()
使所有 my_lib.so 符号对我的应用程序可用?
Upd:我意识到与共享库的显式链接而不将其标记为DT_NEEDED
可以解决问题。但我不知道如何ld
做到这一点。