代码之家  ›  专栏  ›  技术社区  ›  Richard Levasseur

如何构建既需要libstdc++.so.5又需要libstdc++.so.6的应用程序?

  •  8
  • Richard Levasseur  · 技术社区  · 16 年前

    我想先说一句重要的话 我不是C/C++程序员 很少

    我们的代码使用libstdc++.so.6(我想是gcc 3.4)。我们有使用libstdc++.so.5(我认为是gcc2.something或3.2)的第三方预编译(封闭源代码)库。这是在linux上实现的。我们有一个.a和.so版本的第三方库。

    如果我忘记了一些关键信息,请让我知道-我几乎不知道什么与这些东西相关。我意识到一个完整的答案可能是不可能的;我真的在寻找方向和指引。静态链接这个,动态链接那个,重建那个,预构建某某,切换到版本x,或者符号链接quizdoodle,等等。

    更新:

    我们试着使用 dlopen 具有 RTLD_LOCAL 将第三方库与我们应用程序的其余部分隔离。这似乎已经发生了 主要地 然而,由于未知的原因,我们仍然存在大量内存泄漏。我们怀疑,当我们打电话时 dlopen ,第三方库引入了符号,如 malloc

    为了搞笑,我们尝试将第三方库放入 LD_PRELOAD ,然后运行我们的应用程序,内存泄漏似乎完全消失了。

    4 回复  |  直到 11 年前
        1
  •  7
  •   pobedim    16 年前

    您可以尝试围绕第三方库构建包装器库:使用该库的静态版本+将其与静态标准库链接(-static libgcc-确保通过-L获取正确的版本)。要做的重要事情是正确关闭此包装器库,即只导出原始第三方库中的符号,其他所有内容都应隐藏。这样,包装器库将公开应用程序所需的所有符号,并将标准内容封装在其中。注意:它不能保证工作,特别是当您的代码和第三方代码之间共享某些内存操作时(例如,您在代码中分配内存,在第三方中取消分配内存)。。。在这种情况下,唯一的选择是将此第三方库保留在不同的进程空间中。

    我不认为上面提到的动态选项会起作用,因为你会遇到完全相同的问题——就在稍后。

    一般来说,最好不要在同一进程空间中混合使用具有不同运行时间的二进制文件。这几乎总是导致灾难。

        2
  •  4
  •   Steven Schlansker    16 年前

    请您的供应商提供一个更新版本的库,该库使用的东西不会过时得可怕。如果失败了,您可以查看新应用程序是否仍能与旧版本的库一起工作,如果需要,还可以将其移植回去。尝试使用同一个库的两个不同版本会带来麻烦,我认为您不会找到可接受的解决方案。

        3
  •  2
  •   Martin    16 年前

    虽然同时将libstdc++.so.6和libstdc++.so.5链接到您的应用程序很容易,但它的行为基本上是未定义的,因为符号基本上是偶然从任意一个库中获取的。

    IMO成功的最佳方法是在旧系统(使用兼容的gcc,例如gcc 3.3)上围绕第三方库构建自己的应用程序,并让它通过IPC(例如共享内存)与主应用程序通信。这边,不行

        4
  •  1
  •   Michael Ekstrand    16 年前

    虽然到目前为止给出的其中一种方法可能有效,但我认为更安全的说法是,您不能以可靠的方式直接执行此操作。如果您使用完全基于C的API(只有C兼容的结构、由malloc/free管理的内存等)编写包装器,那么您可能能够使用pobedim的解决方案。但是,如果需要交换C++结构,则不安全,因为即使可以使链接发生,不同的标准库实现也会用于同一对象。此外,C++ abi在5和.6的代码基础之间可能不兼容(我不记得几年前GNU C++的主要变化是如何发生的,与标准库SONAMS有关)。

    我认为解决这个问题最安全的方法是使用多进程方法,在您的应用程序和建立在相关库上的资源/计算服务器进程之间使用某种IPC。您可以使用CORBA、D-Bus、Sun RPC或管道或套接字上的某种特殊协议来完成这项工作。我在尝试在64位应用程序中使用封闭源代码32位代码时就做到了这一点,而且效果很好。您将看到性能命中,但您也将完全回避在单个进程中尝试混合C++运行库所固有的问题。