Linux库调用可执行文件中命名模糊的函数-这可能吗? 我有一个问题,我写了一个嵌入式Linux C++应用程序,它由一个可执行文件和一个动态链接库组成。可执行文件调用的函数是库中的入口点之一,但该函数行为不正常。我研究过使用gdb,发现库函数(本应调用库中的另一个函数xyz())实际上调用了可执行文件中同名的函数xyz()

Linux库调用可执行文件中命名模糊的函数-这可能吗? 我有一个问题,我写了一个嵌入式Linux C++应用程序,它由一个可执行文件和一个动态链接库组成。可执行文件调用的函数是库中的入口点之一,但该函数行为不正常。我研究过使用gdb,发现库函数(本应调用库中的另一个函数xyz())实际上调用了可执行文件中同名的函数xyz(),linux,gcc,dynamic-library,Linux,Gcc,Dynamic Library,我很惊讶这会发生,所以也许我在做一些愚蠢的事情。库不是在自身内部链接而不引用可执行文件吗?如果可执行文件错误地调用了库中的abc(),而不是可执行文件中的abc(),这将更有意义,因为它至少与库相链接,尽管在这种情况下链接器会发现双重定义吗?或者优先考虑本地功能 我可以重命名我的函数,使它们没有匹配的名称,但我想了解发生了什么。我在这方面没有太多经验,也没有使用gcc工具的经验。首先,我认为在上述情况下发生的事情可能吗 可执行文件和库都会调用另一个库。 我正在使用的库的link命令是: powe

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

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

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


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
    ,公共函数的名称类似于
    SSL\u set\u mode()
    ,因此避免了不必要的符号冲突
  • 不要从库中导出本应为私有的符号。如果未从库中导出符号,则动态链接器将使用库中的本地符号
    #pragma visibility
    是你的朋友。看
如果具有重复符号的库是第三方库,且其作者未遵循上述建议,则必须重命名函数,或者要求作者更新库

编辑

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


详细信息请参见上面的链接。

可执行文件的链接命令如何?它是否使用了
-rdynamic
?@WumpusQ.Wumbley:它没有使用-rdynamic。它使用-Wl,-rpath-link,../otherlibpath-lotherlibname-Wl,-Bstatic-lxxx-Wl,-Bdynamic-lmylibrary,其中lxxx是静态链接到的库,otherlib是动态库,它们都链接到我上面提到的库。谢谢你的提问。如何防止可执行文件导出符号?它似乎导出了所有这些符号(使用nm-D或readelf--dyn syms),但我认为可执行文件通常不想导出任何符号..进一步试验后,可执行文件导出的函数名符号正是与它所链接的动态库中的函数名相匹配的符号。为了停止它,我在可执行文件的编译和链接命令中添加了-fvisibility=hidden。所以问题就解决了。库现在调用它自己版本的函数。当您使用
-fvisibility=hidden
编译可执行文件时,它可能会工作,因为库看不到可执行文件中的符号。但库之间仍然存在符号不匹配的可能性。最好限制库符号的可见性-请参见编辑。
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