同一个应用程序中的同一库的两个版本

Two versions of same library in one app

本文关键字:两个 版本 应用程序 同一个      更新时间:2023-10-16

我有两个版本(具有几乎相同的API)的相同共享库。我必须在同一应用程序中使用它们。我知道如何解决标题中的名称冲突——我只会像这个一样导入它们

namespace version1 {
#include "version1/library.h"
}
namespace version2 {
#include "version2/library.h"
}

但我不知道如何解决链接冲突——库是动态链接的。第一个版本在自定义库文件夹中创建以下结构:

libsomething.so -> libsomething.so.2
libsomething.so.2 -> libsomething.so.0.8.31.1
libsomething.so.0.8.31.1

第二个:

libsomething.so -> libsomething.so.2
libsomething.so.2 -> libsomething.so.0.8.32
libsomething.so.0.8.32

我的目标环境是Linux机器。

上下文:

我有库的来源,但它们是自动下载和编译的,所以我想避免在CMakeProject中更改这些库的任何内容,但如果其他选项太复杂,我可以这样做。我更喜欢在编译后对这些库进行更改的解决方案,例如更改soname。但是,如果我必须在应用程序代码中做一些复杂的事情来使用这些库,我更喜欢对这些库项目进行更改并维护它们(因为版本可能会更改,但总会有两个版本——一个版本可能会永远设置,永远不会更新,所以我更喜欢更改这个不变的版本)。

我的目标环境是Linux机器。

看起来,基于符号链接的两个版本的库都具有相同的SONAME,即libsomething.so.2

这完全排除了将它们链接到同一个可执行文件,并在运行时使用Linux的运行时加载程序加载这两个文件。它没有这种能力。

我看到的唯一选项是可执行文件使用dlopen(3)库调用手动加载每个库。之后,您需要使用dlsym(3)或dlsymv3(3)在每个加载的库中查找每个函数的地址,并间接调用它。

注意,dlsym()dlsymv3()采用每个函数名称的损坏版本。这将取决于您来弄清楚每个函数的名称有哪些。

没有人声称这会很容易,但在绝对没有其他选择的情况下,这是可行的。