【问题标题】:How to include different versions of same static library in an application?如何在应用程序中包含同一静态库的不同版本?
【发布时间】:2016-06-06 11:29:07
【问题描述】:

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

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

我没有这些库的源代码。

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

【问题讨论】:

    标签: linker shared-libraries static-libraries


    【解决方案1】:

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

    您不能:确保以独立的方式构建 AA.soBB.so,并且您无法重新构建它们。

    您可以做的是尝试通过在运行时使用dlopen("AA.so", RTLD_LAZY|RTLD_LOCAL)BB.so 加载库来完成这项工作,并且希望库不这样做不要互相踩踏。

    理论上(RTLD_LOCAL 是重要的一点)应该可以工作。在实践中,这仍然有很多方法可以打破。你正在冒险进入非常危险的地方。

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

    更新:

    我相信共享对象不依赖于其他任何东西,从这个意义上说,它们是自包含的。

    “不依赖任何东西”部分是必要的,但还不够。

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

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

    【讨论】:

    • 谢谢@Employed 俄罗斯人!但我相信共享对象不依赖于其他任何东西,从这个意义上说,它们是自包含的。所以理想情况下,无需任何额外步骤,AA.so 应该使用 CC.a 版本 1,BB.so 应该使用 CC.a 版本 2,对吗?
    猜你喜欢
    • 1970-01-01
    • 2016-09-03
    • 1970-01-01
    • 1970-01-01
    • 2019-11-18
    • 1970-01-01
    • 2013-07-08
    • 2023-03-30
    • 1970-01-01
    相关资源
    最近更新 更多