Linux 如何链接具有许多冲突函数的两个共享库

Linux 如何链接具有许多冲突函数的两个共享库,linux,gcc,g++,shared-libraries,function-interposition,Linux,Gcc,G++,Shared Libraries,Function Interposition,我目前正在与linux上的两个第三方共享库(A.so和B.so)链接。问题是这两个so都与另一个库静态链接,因此a.so和B.so中大约有400个函数具有相同的名称。 当我编译并使用-lA-lB或-lB-lA链接时,根据函数插入的顺序,函数分别从A或B中拾取,这导致了问题,代码无法运行。我想知道是否有办法将函数名绑定到它们的库,这样两个库都可以链接和使用?因为这些重叠的函数名是在A和B内部调用的,所以我不能使用像objcopy之类的东西。dlopen会有帮助吗 我想知道是否有办法将函数名绑定到它

我目前正在与linux上的两个第三方共享库(A.so和B.so)链接。问题是这两个so都与另一个库静态链接,因此a.so和B.so中大约有400个函数具有相同的名称。 当我编译并使用-lA-lB或-lB-lA链接时,根据函数插入的顺序,函数分别从A或B中拾取,这导致了问题,代码无法运行。我想知道是否有办法将函数名绑定到它们的库,这样两个库都可以链接和使用?因为这些重叠的函数名是在A和B内部调用的,所以我不能使用像objcopy之类的东西。dlopen会有帮助吗

我想知道是否有办法将函数名绑定到它们的库,这样两个库都可以链接和使用

当两个库链接时,它们应该控制它们导出的符号,并且应该隐藏“其他”库,但它们没有

我能帮忙吗

是:如果您
dlopen(“A.so”,RTLD_LOCAL)
dlopen(“B.so”,RTLD_LOCAL),则两个库都不会添加到全局作用域,并且它们不会相互“看到”

您必须从
A.so
B.so
中明确查找所需的符号,但这是您所能做的最好的事情

更新:

是否有一种快速方法可以链接到静态库,而无需在构建so时从“其他”库导出符号

最好在应该导出的符号上使用
-fvisibility=hidden
标志和
\uuuu属性((可见性(“默认”))
。例如:

#define EXPORTED __attribute__((visibility("default")))

struct Foo {
  void EXPORTED ExportedFunction();
  void EXPORTED AnotherExportedFunction();
  void InternalFunction();
};

void Foo::ExportedFunction() { }
void Foo::AnotherExportedFunction() { }
void Foo::InternalFunction() { }


gcc -shared -fPIC -o foo.so foo.cc
nm -CD foo.so  | grep Foo::
00000000000005fc T Foo::ExportedFunction()
0000000000000610 T Foo::InternalFunction()
0000000000000606 T Foo::AnotherExportedFunction()
没有显式的导出控制,所有内容都会被导出(包括
InternalFunction
我们不想要的内容)

瞧,我们唯一明确想要出口的东西是

我想知道是否有办法将函数名绑定到它们的库,这样两个库都可以链接和使用

当两个库链接时,它们应该控制它们导出的符号,并且应该隐藏“其他”库,但它们没有

我能帮忙吗

是:如果您
dlopen(“A.so”,RTLD_LOCAL)
dlopen(“B.so”,RTLD_LOCAL),则两个库都不会添加到全局作用域,并且它们不会相互“看到”

您必须从
A.so
B.so
中明确查找所需的符号,但这是您所能做的最好的事情

更新:

是否有一种快速方法可以链接到静态库,而无需在构建so时从“其他”库导出符号

最好在应该导出的符号上使用
-fvisibility=hidden
标志和
\uuuu属性((可见性(“默认”))
。例如:

#define EXPORTED __attribute__((visibility("default")))

struct Foo {
  void EXPORTED ExportedFunction();
  void EXPORTED AnotherExportedFunction();
  void InternalFunction();
};

void Foo::ExportedFunction() { }
void Foo::AnotherExportedFunction() { }
void Foo::InternalFunction() { }


gcc -shared -fPIC -o foo.so foo.cc
nm -CD foo.so  | grep Foo::
00000000000005fc T Foo::ExportedFunction()
0000000000000610 T Foo::InternalFunction()
0000000000000606 T Foo::AnotherExportedFunction()
没有显式的导出控制,所有内容都会被导出(包括
InternalFunction
我们不想要的内容)


瞧:我们唯一明确想要导出的东西是。

Q:你有没有可能从C.a中提取所有内容并将其变成一个共享库?@paulsm4你确定这会解决问题?Q:你有没有可能从C.a中提取所有内容并将其变成一个共享库,太好了?@paulsm4你确定这会解决问题吗?谢谢你的评论。刚刚意识到一个问题,对于第三方库,我需要继承它们的类,在这种情况下是否仍然可以使用dlopen?第三方库的开发人员愿意合作,但他们不知道如何隐藏他们使用的“其他”静态库,有没有快速的方法?像gcc中的一些标志一样?更具体地说,为了帮助他们,在构建a.so和B.so时,有没有一种快速的方法可以链接到静态库而不从“其他”库导出符号?只要速度快,他们愿意做出改变。@Daniel我添加了一个例子。谢谢你的评论。刚刚意识到一个问题,对于第三方库,我需要继承它们的类,在这种情况下是否仍然可以使用dlopen?第三方库的开发人员愿意合作,但他们不知道如何隐藏他们使用的“其他”静态库,有没有快速的方法?像gcc中的一些标志一样?更具体地说,为了帮助他们,在构建a.so和B.so时,有没有一种快速的方法可以链接到静态库而不从“其他”库导出符号?只要速度快,他们愿意做出改变。@Daniel我添加了一个例子。