PyDLL 不适用于不同的 Python 版本

PyDLL does not work across different Python versions

提问人:macroland 提问时间:11/15/2023 最后编辑:macroland 更新时间:11/15/2023 访问量:36

问:

我正在使用PyDLL函数将DLL绑定到Python。

从 Python 端:

import ctypes as _ct
_path = _parent_path(__file__) / "scisuit_pybind"
pydll = _ct.PyDLL(str(_path))

pydll.c_root_bisect.argtypes = [_ct.py_object, _ct.c_double, _ct.c_double, _ct.c_double, _ct.c_int, _ct.c_char_p, _ct.c_bool]
pydll.c_root_bisect.restype = _ct.py_object

从 C++ 方面:

#define EXTERN \
    extern "C" DLLPYBIND

EXTERN PyObject * c_root_bisect(PyObject * FuncObj,
    double a,
    double b,
    double tol = 1e-5,
    int maxiter = 100,
    const char* method = "bf",
    bool modified = false);

案例有:

  1. 工程:使用 Python 3.10.6 编译 DLL,并使用 Python 3.10.6 运行它。使用 Python 3.11 运行时失败
  2. 工程使用 Python 3.11 编译 DLL 并使用 3.11 运行。使用 Python 3.10 运行时失败

错误:self._handle = _dlopen(self._name,模式)

我错过了什么?


编辑1

一个快速的解决方法(可能不是最好的)是为 3.x 版本(目前我为 3.10 和 3.11 构建了它们)构建 DLL(受影响的 DLL 很小,大约 170 KB),然后从 Python 端构建:

_DLLname= "scisuit_pybind"
if sys.version_info.minor == 10:
    _DLLname= "scisuit_pybind310"

_path = _parent_path(__file__) / _DLLname
蟒蛇 C++

评论


答:

1赞 TooTone 11/15/2023 #1

这是意料之中的。Python 应用程序二进制接口 (ABI) 仅在主要版本中稳定,例如,为 3.10.1 构建的任何内容也适用于 3.10.2。但是,当 x0 不等于 x1 时,为 3.x0.y0 构建的东西将不适用于 3.x1.y1。

例如,参见 https://peps.python.org/pep-3149/

由于 ABI 中的更改,为不同 Python 主要版本编译的扩展模块彼此不兼容。

使用 pybind11 构建的 Python 模块也会发生同样的情况。

评论

0赞 macroland 11/15/2023
我已经添加了“编辑”部分,解决了该问题。我意识到,例如,每个 ABI 具有不同文件名 (numpy-1.26.2-cp310-cp310-win_amd64.whl) 的 numpy 版本。我正在使用 toml 文件,但我无法实现这一点,因为所有文件名最终都是projectname-py3-any-none.whl