我目前正在Linux上与两个第三方共享库(A.so和B.so)建立链接。问题是这两者都与另一个库静态链接,因此A.so和B.so的大约400个函数具有相同的名称。 当我使用-lA -lB或-lB -lA进行编译和链接时,由于函数插入导致问题并且代码无法运行,因此根据顺序从A或B单独拾取函数。我想知道是否有办法将函数名称绑定到它们的库,这样两个库都可以链接和使用?因为那些重叠的函数名在A和B内部被调用,所以我不能使用像objcopy这样的东西会dlopen帮助吗?
答案 0 :(得分:4)
我想知道是否有办法将函数名绑定到它们的库中,这样两个库都可以链接和使用?
当链接两个库时,它们应该控制它们导出的符号,并且应该隐藏“其他”库,但它们没有...
会帮助吗?
是:如果您dlopen("A.so", RTLD_LOCAL);
和dlopen("B.so", RTLD_LOCAL);
,那么这两个图书馆都不会被添加到全局范围内,也不会相互“看到”。
您必须从A.so
和B.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à:我们只明确想要出口的东西是。