如何提高基于PyO3的库在不同Python版本间的可移植性?

0 投票
1 回答
569 浏览
提问于 2025-06-18 04:04

我在我的系统上用PyO3创建了一个库,使用的是Python 3.5.2。这个库的.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使用我的库)?或者我在运行时能做些什么,让这个库仍然可以正常工作?

相关问题:

  • 暂无相关问题
暂无标签

1 个回答

2

Python 的扩展模块根本不应该链接到 libpython。这样做的话,Python 的符号会保持未解决状态,动态加载器会在加载这个模块的 Python 解释器中查找这些符号。这样一来,你甚至可以在一个静态链接的 Python 中使用你的模块!

rust-cpython 有一个 extension-module 的功能,而 PyO3 似乎也借鉴了这个功能。你可以在你的 Cargo.toml 文件中启用它:

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

撰写回答