【问题标题】:Python extension module with embedded python calls wrong library带有嵌入式 python 的 Python 扩展模块调用错误的库
【发布时间】:2014-12-10 18:20:57
【问题描述】:

我有一个 python 扩展模块 (2.7)(由 swig 生产),它本身链接到一个链接到 Python 3.33 的库。即使模块链接到 3.33 版本,当它被实例化时,它也会调用 2.7 定义的 PyFunc,而不是 3.33 中定义的 PyFunc。这仅在 linux 上发生,并且在 Windows 上运行良好。我是否需要传递特定的链接器标志以避免此类问题?

谢谢!

【问题讨论】:

  • 你有链接到 Python 3.X 的库的代码吗?这个链接是静态完成的还是通过 dlopen/LoadLibrary 完成的?
  • 是的,我有代码,它与 gcc 命令行上的 -lpython 动态链接。你建议静态链接吗?这将阻止我加载其他模块,而这些模块无法查找动态库..

标签: python c++ linux gcc


【解决方案1】:

在 Windows 下,DLL(Linux 共享对象模拟)必须在链接阶段解析其所有外部符号,因此在构建扩展程序期间,扩展程序与 python 3.0 DLL 隐式链接并且一切正常(没有看到 MSVC 命令行,我几乎可以肯定扩展是链接到位于类似 c:/python33/libs/python33.lib 下的存根库)

另一方面,在 Linux 下,共享对象默认链接机制 isn't resolving all the external symbols,因此 -lpython 的 LD 规范可能会在运行时解析为基于 2.7 的已加载共享对象...

所以你有两个选择:

  1. 既然你得到了源代码,在 Linux 下你可以通过dlopendynamically 加载 libpython33.so 以避免这个“DLL 地狱”

  2. 静态方法,你应该指定python3.3的确切位置,而不是像/usr/lib/python3.3/libpython33.so这样的“模糊”-lpython(解析为python2.7) /p>

【讨论】:

  • 当我用 dlopen 打开时会发生什么?我是否必须从 .so 文件中重新获取所有函数指针,而不是调用从头文件和 -l 标志导入的函数指针?
  • 一般来说,dlopen 的经典用法(将 .so 作为插件使用)涉及 dlsym 的使用(通过名称等获取函数指针)在您的情况下,我们唯一的目的是简单地加载 正确 .so 版本(3.3 而不是 2.7)所以你不需要使用函数指针,你的函数调用将被解析为正确的 DLL(我当然在这里假设,没有 IMO 应用的头/接口不匹配对你的情况)。如果我是你,我会选择第二个选项,看看会发生什么
  • 这不能与 2.7 调用模块混淆吗?或者符号仅限于启动 dlopen 的模块?
  • 符号不仅限于启动模块...我会尝试更好地澄清自己应该执行什么(IMO)-正如我所说,在我的回答中,您的扩展针对 2.7 API 的原因是b / c它以“模糊”的方式链接到python lib(-lpython解析为python2.7)我对你的rec在你的makefile中(让我们忽略dlopen / dynamic方法)是指定显式 要链接的 python 3.3 的路径(我的答案中的第二个项目符号)-通过这样做,您将获得以下信息: 1. Py 2.7 已执行 2. 您的扩展正在加载/使用。 3. 加载 Py 3.3 并调用它
  • 好的明白了。这不能用 ldd 验证吗?在我启动我的可执行文件之前,我强制使用 LD_LIBRARY_PATH 查找库,但更像是该进程已经加载了与 3.3 库中的符号匹配的符号......顺便说一句,我会尝试你的建议......
猜你喜欢
  • 2021-02-10
  • 1970-01-01
  • 1970-01-01
  • 2010-12-13
  • 2012-01-19
  • 2018-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多