如何链接两个具有许多冲突功能的共享库

时间:2013-02-04 04:43:00

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

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

1 个答案:

答案 0 :(得分:4)

  

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

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

  

会帮助吗?

是:如果您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()

Voilà:我们只明确想要出口的东西是。