让我解释一下这个场景。我们有一个遗留的C ++编译的.so库。此库中的函数使用extern "c" {}
声明,因此C和C ++程序都可以使用该库,并且由于某种原因,它是使用--static-libgcc
选项创建的。
这个旧图书馆很旧,很难维护。现在我们已经设法写了它的替代,但是用C语言编写。假设旧库名为libfoo.so(旧),新库名为libfoo.so(新)。对于给定的bar.o,它可以与旧的或新的libfoo.so链接以创建可执行文件,例如bar.exe。但是bar.exe只能运行它之前链接的相同的.so库,换句话说,这两个库是不可互换的。
编辑#1 :我创建了一个名为libfoo.so的符号链接,指向libfoo.so(旧)或libfoo.so(新)。此符号链接libfoo.so在运行时位于LD_LIBRARY_PATH中。
编辑#2 :当我将bar.o与旧的libfoo.so链接并生成bar.exe时,如果我使用新的libfoo.so运行此bar.exe,则报告错误为{{ 1}}。通过undefined symbols
这两个libfoo.so,我可以在旧的符号中找到这些符号,但不能在新的符号中找到。这些符号类似于nm
,它是一个C ++ lib错位名称(虽然它是由_ZSt4cerr
引入的),当然新的libfoo.so不包含那些符号。
编辑#3 :如果我只是使用g ++而不是gcc编译和链接C代码,它是否有意义?
我该如何实现?
编辑#4 :今天我设法使用g ++(使用静态libgcc,静态libstdc ++)编译/链接新的C编程libfoo,这可能导致所有c ++符号都包含在libfoo中。所以。这可以使一切顺利进行,但不是我真正想要的。
答案 0 :(得分:2)
如果你建立并链接新的,你可以让它与旧的链接?听起来你生成了一个二进制兼容的库,但只是在一个方向上。
答案 1 :(得分:1)
编辑#2帮助。
基本上你的 bar.exe 正在尝试为该库进行C ++运行时初始化。
您必须至少提供相同损坏名称的空实现,以便 bar.exe 可以动态搜索您的.so并查找/调用它们。
如果你不那么幸运,你可能需要让这些函数做一些有意义的事情,以便上层代码解释为成功。
祝你好运
答案 2 :(得分:0)
给他们相同的名字并放入不同的目录。使用LD_LIBRARY_PATH env。变量,用于在任何其他目录之前设置所需库的目录。