gpt4 book ai didi

Linux 库在可执行文件中调用含糊不清的命名函数——这可能吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:40:48 25 4
gpt4 key购买 nike

我编写的嵌入式 linux C++ 应用程序存在问题,该应用程序由可执行文件和动态链接库组成。可执行文件调用一个函数,该函数是库中的入口点之一,但该函数运行异常。我使用 gdb 进行了调查,发现应该调用库中另一个函数 xyz() 的库函数实际上在可执行文件中调用了同名函数 xyz()。

我很惊讶这会发生,所以也许我在做一些愚蠢的事情。库不是在不引用可执行文件的情况下在自身内部链接的吗?如果可执行文件错误地调用了库中的 abc() 而不是可执行文件中的 abc() ,这会稍微更有意义,因为它至少与库链接,尽管在那种情况下链接器会发现双重定义?还是优先考虑本地功能?

我可以重命名我的函数,使它们都没有匹配的名称,但我想了解发生了什么。我在这方面或使用 gcc 工具方面没有太多经验。首先,我认为上述情况是否可能发生?

可执行文件和库都会调用另一个库。我正在使用的库的链接命令是:

powerpc-unknown-linux-gnuspe-g++-4.9.3 aaa.o bbb.o [etc] -shared -o libmylibary.so -L ../otherlibpath -Wl,-rpath-link,../otherlibpath -lotherlibname

最佳答案

这就是动态链接器的工作方式。可执行文件中的符号比动态库中的符号具有更高的优先级。动态库设计者必须意识到这一点。她必须采取措施避免不必要的符号不匹配。大多数图书馆使用:

  • 如果是 C++,请使用命名空间。从库中导出的所有符号都应位于库命名空间中。
  • 在 C 的情况下,为所有导出的符号使用名称前缀或后缀。例如,OpenSSL 库使用前缀 SSL_,公共(public)函数的名称类似于 SSL_set_mode(),因此避免了不需要的符号冲突。
  • 不要从应该是私有(private)的库中导出符号。如果符号未从库中导出,则动态链接器使用库中的本地符号。 #pragma visibility 是你的 friend 。参见 https://gcc.gnu.org/wiki/Visibility

如果具有重复符号的库是第 3 方库,并且其作者未遵循上述建议,那么您必须重命名您的函数,或者可能要求作者更新库。

编辑

导出/不导出可以由#pragma visibility指令控制(gcc特定扩展):

void exported_function1(int);
void exported_function2(int);
#pragma GCC visibility push(hidden)
void private_function1(int);
void private_function2(int);
#pragma GCC visibility pop

在上面的链接中有详细信息。

关于Linux 库在可执行文件中调用含糊不清的命名函数——这可能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42983807/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com