linux - 定义相同函数名称的两个 linux 共享对象之间的冲突

标签 linux pyqt ld python-embedding python-extensions

我的问题涉及 Python、Qt、PyQt 和其他东西,但问题实际上是关于 Linux 的 ld.so 实际如何工作。

问题

如果一个程序加载两个不同的共享库,它们都具有相同的入口点名称(即它们都定义了具有相同名称和签名的函数),它如何知道它调用的是哪个版本?

我的问题

我有一个第三方专有的 Linux 应用程序,它是用 C++ 编写的(尽管原始语言无关紧要)并且动态链接到 Qt3.3。该应用程序嵌入了一个 python 解释器,可用于为其编写脚本。

您甚至可以使用应用程序的嵌入式 python 而不是原始的 python,使用如下命令:

/path/to/the/program/python

它显示以下内容:

Python 2.7.1 (r271:86832, Sep 16 2011, 18:16:32) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>

我使用 gcc 4.1.2 从源构建并安装了 PyQt4,与系统也有的 Qt4 库相对应。我相信构建是成功的,因为我可以使用以下命令运行一个小型 PyQt4 应用程序:

/path/to/the/program/python mypyqtapp.py

但是,如果我用它的 GUI 加载程序并加载相同的脚本,它会在第一次 PyQt4 调用时崩溃,这是 QApplication 类的实例。

由于python环境相同,我怀疑可能是Qt3和Qt4之间的某种共享库冲突。但是,命令 strace -e trace=file 显示 python 在这两种情况下都定位并加载了正确的 Qt4 库。

所以,我的问题是,如果一个程序加载了两个定义相同函数的共享不同库,它如何知道它调用了正确的函数? linux 加载程序 ld.so 是否以某种方式使用文件名或其他名称限定入口点?我怀疑我的问题可能就在那里,应用程序最终加载了两个不同的 QApplication 实例并且调用了错误的实例,但是 ld.so 实际上是如何在内部转义的我。

也可能是我的问题是由完全不同的原因引起的。

谢谢。

最佳答案

仅在linkage(ld) 阶段检测到冲突符号,loader(ld-linux.so) 不检查冲突符号。

当多个库提供重复符号时,使用第一个加载的库。

实际上有人可以利用此功能。通过提供 LD_PRELOAD=overwrite.so,overwrite.so 可以覆盖程序所需的任何功能。

关于linux - 定义相同函数名称的两个 linux 共享对象之间的冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17864302/

相关文章:

python - 在 Python 中 session 终止时获取信号

c - 在Linux上使用套接字发出https请求

python - PyQt5 导入 QtGui 失败

python - threading.current_thread() 中的 Dummy 是什么?

python - 没有来自 QProcess 的 readyReadStandardOutput 信号

linux - 没有管理员权限,如何找到 ld 搜索的目录?

php - UTF-8贯穿始终

ios - ld:架构 armv7 Xcode 项目的 xx 重复符号

c - 将共享库链接到静态库

c++ - 以分钟为单位查找与 GMT 的本地时区差异