提问人:macroland 提问时间:11/15/2023 最后编辑:macroland 更新时间:11/15/2023 访问量:36
PyDLL 不适用于不同的 Python 版本
PyDLL does not work across different Python versions
问:
我正在使用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);
案例有:
- 工程:使用 Python 3.10.6 编译 DLL,并使用 Python 3.10.6 运行它。使用 Python 3.11 运行时失败。
- 工程使用 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
答:
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
评论