python - 如何使基于 PyO3 的库在 Python 版本之间更具可移植性?

标签 python rust shared-libraries pyo3

我有一个使用 Python 3.5.2 在我的系统上使用 PyO3 创建的库。 .so 文件链接到对应的 libpython3.5m 文件:

$ ldd my_library.so
    linux-vdso.so.1 =>  (0x00007ffffc823000)
    libpython3.5m.so.1.0 => /usr/lib/x86_64-linux-gnu/libpython3.5m.so.1.0 (0x00007fcac34b0000)
    ...

但是,如果我尝试在具有不同 Python 次要版本(例如,3.6.9 或 3.7.3)的另一个系统上使用我的库,则该库不存在:

$ ldd my_library.so
    linux-vdso.so.1 (0x00007fffefaae000)
    libpython3.5m.so.1.0 => not found
    ...

因此,我不能使用我的库:

$ python3
Python 3.6.9 (default, Apr 18 2020, 01:56:04)
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import my_library
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: libpython3.5m.so.1.0: cannot open shared object file: No such file or directory

有没有一种方法可以更通用地将我的库链接到 libpython 以适应这些次要版本更改,或者至少允许向后兼容(在较新版本上构建但允许较旧版本的 Python 也使用我的库)?或者我可以在运行时做些什么来让库仍然运行?

最佳答案

Python 扩展模块根本不应该链接到 libpython。 Python 符号将保持未解析,动态加载器将在加载模块的任何 python 解释器中查找它们。这样你甚至可以将你的模块与静态链接的 Python 一起使用!

rust-cpython 有一个 extension-module这个功能和 PyO3 似乎已经复制了它。
您可以在 Cargo.toml 中启用它:

[dependencies]
pyo3 = { version = ..., features = [ "extension-module" ] }

关于python - 如何使基于 PyO3 的库在 Python 版本之间更具可移植性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61878344/

相关文章:

rust - 如何在 Rust 中修复 ".. was mutably borrowed here in the previous iteration of the loop"?

java - 为 Raspberry Pi 编译 JD2XX

c++ - Dependency Hell : linux . 所以插件动态加载

python - matplotlib运行时错误: In select_charmap: Could not set the charmap using latex

python - HTTP Negotiate windows vs. Unix 服务器实现使用 python-kerberos

python - 在 Linux 中使用 SWIG for Python 转换字符串

c - 使用我自己的库 : implicit declaration of function

python - Rabbitmq:channel.start_consuming()不会消耗

rust - Rust 中的组合运算符和管道转发运算符

rust - 如何为 move 的 Vec<> 参数调用 Vec<>::append()?