如何在应用程序中包含同一个静态库的不同版本?

How to include different versions of same static library in an application?

我有一个包含 AA.so 的应用程序。 AA.so 内部包含 CC.a 版本 1。

现在我必须将 BB.so 添加到同一个应用程序以获得其他一些功能。 BB.so 还包括 CC.a 版本 2。

我没有这些库的源代码。

我的问题是 - 如何确保来自 AA.so 的函数调用转到 CC.a 版本 1 而来自 BB.so 的函数调用转到 CC.a 版本 2?

How to make sure that function calls from AA.so go to CC.a version 1 and calls from BB.so go to CC.a version 2?

你不能:确保以独立的方式构建 AA.soBB.so,你不能重建它们。

你可以做的是尝试通过在运行时间使用dlopen("AA.so", RTLD_LAZY|RTLD_LOCAL)加载库来完成这项工作,BB.so也是如此,并且希望图书馆不会互相踩踏。

理论上(RTLD_LOCAL 是重要的一点)应该有效。在实践中,仍有许多方法可以破坏它;你正在冒险进入非常危险的地方。

它今天也可以工作,但是当任一共享库更新时就会中断。您真的 应该与您的图书馆供应商合作,以摆脱这种多版本不兼容的混乱局面。

更新:

I believe shared objects do not depend on anything else and in that sense they are self-contained.

"not depend on anything else" 部分是必要的,但还不够。

通常,共享库 导出 所有全局函数和链接到其中的数据。假设CC.a包含一个全局函数foo;假设此函数的版本 1 和 2 不兼容,并且 fooAA.soBB.so 导出 。在这种情况下,首先加载的库将获胜。如果首先加载 AA.so,那么从 BB.sofoo 的调用将解析为 AA.so 中的定义,您的程序将破坏其状态或崩溃。

要验证不是这种情况,你应该在AA.soBB.so上运行nm -D,并确认从这些库导出的符号的交集是空的。如果不为空,则需要验证两个定义是否兼容。