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

C++ 一个应用程序中的同一库的两个版本,c++,compilation,linker,C++,Compilation,Linker,我有两个相同共享库的版本(使用几乎相同的API)。我必须在同一应用程序中使用它们。我知道如何解决标题中的名称冲突——我将像这样导入它们 namespace version1 { #include "version1/library.h" } namespace version2 { #include "version2/library.h" } 我不知道如何解决链接冲突——库是动态链接的。第一个版本在自定义库文件夹中创建以下结构: libsomething.so ->

我有两个相同共享库的版本(使用几乎相同的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中的任何内容,但如果其他选项太复杂,我可以这样做。我更喜欢在编译后更改这些LIB的解决方案,例如更改soname。但是,如果我不得不在应用程序代码中做一些复杂的事情来使用这些libs,我更喜欢对这些libs项目进行更改并维护它们(因为版本可以更改,但始终会有两个版本——一个版本可能会被永久设置,永远不会更新,所以我更喜欢更改这个不更改的版本)

我的目标环境是Linux机器

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

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

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

请注意,
dlsym()
dlsymv3()
采用每个函数名的损坏版本。这将由您来确定每个函数的损坏名称


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

名称空间不会解决链接问题,除非您重建两个版本的库,以便在各自的名称空间中定义函数。更常见的方法是,对于每个动态链接的库,要设置一个包含指向该库中函数的一组指针的数据结构。是否通过将文件名更改为libsomeghingver1.so.2和libsomeghingver2.so.2这样的文件名来更改so名称以使其更简单?或者如果更改soname,是否需要重新编译库?我在问题的末尾添加了一点上下文。是的,如果你更改了库的名称,那就足够了。你能编辑你的问题,然后告诉我更改库的名称后我要做什么吗?毕竟,如果我与这两个库链接,它们都将具有相同的类和方法。所以,若我从命名空间version1调用例如obj.f(),那个么链接器仍然不知道应该从哪个库链接。对于我的理想解决方案,如果我不必使用dlsym使用加载函数,但通常我希望编写“普通”函数调用。不,如果它们具有相同的名称和类,您将无法与它们链接(实际上是这样,但是来自可执行文件的引用将仅解析为库的一个符号)。这假定所有的名称和类都是不同的。如果名称和类相同,那么基于dlopen的方法是唯一的解决方案。