我遇到了嵌入式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
答案 0 :(得分:1)
这就是动态链接器的工作方式。可执行文件中的符号优先于动态库中的符号。动态库设计者必须意识到它。她必须采取措施避免不必要的符号不匹配。大多数图书馆使用:
SSL_
,公共函数的名称类似于SSL_set_mode()
,因此避免了不需要的符号冲突。#pragma visibility
是你的朋友。请参阅https://gcc.gnu.org/wiki/Visibility 如果具有重复符号的库是第三方库且其作者未遵循上述建议,则您必须重命名您的函数或者可能要求作者更新库。
修改
导出/不导出可能由#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
上面链接的详细信息。