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

最佳答案

我想知道是否有一种方法可以将函数名绑定到它们的库中,以便两个库都可以链接和使用?
当这两个库被链接时,它们应该控制它们导出的符号,并且应该隐藏“另一个”库,但是它们没有…
dlopen有帮助吗?
是:如果您dlopen("A.so", RTLD_LOCAL);dlopen("B.so", RTLD_LOCAL);,则两个库都不会添加到全局作用域,并且它们不会“看到”彼此。
您必须从A.soB.so中显式查找所需的符号,但这是您所能做的最好的事情。
更新:
有没有一种快速的方法可以链接到静态库,而不必在构建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()

沃拉:只有我们明确希望出口的东西。

10-08 14:20
查看更多