【问题标题】:how to link with two shared libraries with many conflicting functions如何链接两个具有许多冲突功能的共享库
【发布时间】:2013-02-04 04:43:00
【问题描述】:

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

【问题讨论】:

  • 问:你有没有机会从 C.a 中提取所有内容并使其也成为共享库?
  • @paulsm4 你确定这能解决问题吗?

标签: linux gcc g++ shared-libraries function-interposition


【解决方案1】:

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

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

dlopen 会帮忙吗?

是的:如果你 dlopen("A.so", RTLD_LOCAL);dlopen("B.so", RTLD_LOCAL);,那么这两个库都不会被添加到全局范围内,它们也不会“看到”对方。

您必须从 A.soB.so 中显式查找所需的符号,但这是您能做的最好的事情。

更新:

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

最好在应该导出的符号上使用-fvisibility=hidden 标志和__attribute__((visibility("default")))。示例:

#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)。

gcc -shared -fPIC -o foo.so foo.cc -fvisibility=hidden
nm -CD foo.so  | grep Foo::
00000000000005bc T Foo::ExportedFunction()
00000000000005c6 T Foo::AnotherExportedFunction()

瞧:只有我们明确想要导出的东西。

【讨论】:

  • 感谢您的评论。刚刚意识到一个问题,对于第三方库,我需要继承他们的类,在这种情况下仍然可以使用 dlopen 吗?第三方库的开发人员愿意合作,但他们不知道如何隐藏他们使用的“其他”静态库,有没有快速的方法来做到这一点?像 gcc 中的一些标志?
  • 更具体地说,为了帮助他们,在构建 A.so 和 B.so 时,是否有一种快速链接到静态库的方法,而无需从“其他”库中导出符号?他们愿意做出改变,只要它快..
  • @Daniel 我添加了一个示例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-03
  • 2011-01-25
  • 1970-01-01
  • 2014-02-18
  • 1970-01-01
  • 2017-07-20
相关资源
最近更新 更多