如何编写一个 .so 库来替换现有的 C++ .so 库?

Posted

技术标签:

【中文标题】如何编写一个 .so 库来替换现有的 C++ .so 库?【英文标题】:How to write C .so library to subsitute existing C++ .so library? 【发布时间】:2010-03-03 12:17:09 【问题描述】:

让我解释一下这个场景。我们有一个遗留的 C++ 编译的 .so 库。这个库中的函数是用extern "c" 声明的,所以这个库可以被C 和C++ 程序使用,另外,由于某种原因,它是用--static-libgcc 选项创建的。

这个旧库非常陈旧且难以维护。现在我们已经设法用 C 语言编写了它的替代品。假设旧库名为 libfoo.so(old),新库名为 libfoo.so(new)。对于给定的 bar.o,它可以与旧的或新的 libfoo.so 链接以创建可执行文件,例如 bar.exe。但是bar.exe只能和之前链接的.so库一起运行,也就是说这两个库是不能相互交换的。

EDIT#1:我创建了一个名为 libfoo.so 的符号链接,以指向 libfoo.so(old) 或 libfoo.so(new)。此符号链接 libfoo.so 在运行时位于 LD_LIBRARY_PATH 中。

EDIT#2:当我将bar.o与旧的libfoo.so链接并生成bar.exe时,如果我用新的libfoo.so运行这个bar.exe,它会报告@987654323的错误@。通过nm这两个libfoo.so,我可以在旧的中找到这些符号,但在新的中找不到。这些符号类似于 _ZSt4cerr,这是一个 C++ lib 重命名的名称(虽然它是由 --static-libgcc 带来的),当然新的 libfoo.so 不包含这些符号。

EDIT#3:如果我只是用 g++ 而不是 gcc 编译和链接 C 代码,是否有意义?

我应该如何实现这个?

EDIT#4:今天我设法用 g++(使用静态 libgcc、静态 libstdc++)编译/链接新的 C 编程 libfoo,这可以导致所有 c++ 符号都包含在 libfoo 中。所以。这可以让一切顺利进行,但不是我真正想要的。

【问题讨论】:

为什么它不能与新库一起运行?您收到什么样的错误消息? 他没有收到错误消息。他正在修理一些没有损坏的东西,只是发出一声巨响。 请参考EDIT#2,我已经更新了我的问题。谢谢! 有人知道这里的解决方案吗?我真的很需要一个。谢谢!!! 【参考方案1】:

如果您构建并与新的链接,您可以让它与旧的链接吗?听起来您生成了一个二进制兼容库,但只是在一个方向上。

【讨论】:

是的。如果我构建并链接到新库,生成的 bar.exe 可以与旧库和新库一起运行。但为什么呢? 这意味着新库的头文件依赖的符号比旧库的要少。 gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html 可能会提供有关二进制兼容共享库的内容和方式的更多见解。【参考方案2】:

Edit#2 有帮助。

基本上,您的 bar.exe 正在尝试为该库进行 C++ 运行时初始化。

您必须至少提供相同名称的空实现,以便 bar.exe 可以动态搜索您的 .so 并找到/调用它们。

如果你不太幸运,你可能需要让这些函数做一些有意义的事情,上层代码会将其解释为成功。

祝你好运

【讨论】:

或者,更简单的答案,C .so 替换 C++ .so 不实用...? :(【参考方案3】:

给他们相同的名字并放入不同的目录。使用 LD_LIBRARY_PATH 环境。在任何其他目录之前使用所需库设置目录的变量。

【讨论】:

以上是关于如何编写一个 .so 库来替换现有的 C++ .so 库?的主要内容,如果未能解决你的问题,请参考以下文章

java - 如何将Java hashMap内容的全部放在另一个上,但不替换现有的键和值?

如何测试共享对象/共享库是否已正确编译?

如何使用 Tokio 编写异步方法?

将* .SO库包含在Java项目中(Linux)

将现有的 vuejs 应用程序转换为使用 nuxt s-s-r 有多难?

如何将 Qt 集成到现有的 C++ 项目中