由于您无法重建任何一个库,并且由于符号冲突而不允许这些库驻留在同一“动态链接器命名空间”中,因此您唯一的选择是isolate them.
您可以通过使用来实现dlopen("lib*.so", RTLD_LOCAL)
(对于其中一个或两个库),而不是直接链接到它们。
如果您只需要来自例如的一些符号,这可能是可行的。libfoo.so
-- 你可以简单地使用dlsym
而不是直接调用函数。
如果您对这两个库有“太多”依赖项,则另一个解决方案可能是构建一个“插入器”库。假设你想介入libbar.so
,你需要bar1()
, bar2()
, ... bar1000()
从中。
编写(或使用简单的 Perl 脚本生成)一个如下所示的源文件:
static void *handle;
void *bar1()
{
static void* (*pfn)(void *arg1, void *arg2, void *arg3, ..., argN);
if (pfn == NULL) {
if (handle == NULL)
handle = dlopen("libbar.so", RTLD_LOCAL|RTLD_LAZY);
pfn = dlsym(handle, "bar1");
}
return (*pfn)(arg1, arg2, ..., argN);
}
... repeat for all other libbar functions you depend on
现在编译此源并将其链接到libbar_interposer.so
并将您的应用程序链接到它(这不适用于C++
由于名称修改,仅适用于简单的C
)。瞧,应用程序的源代码没有更改,并且您仍然隔离了libbar.so
因此它的符号对应用程序的其余部分不可见,特别是不会与libpng
.