NumPy 2.0 的 ABI 变更导致旧 C 扩展无法运行:禁用内部符号、重排 PyArray_Descr 结构体、收紧 import_array() 调用机制,且构建环境不匹配(如 pip wheel 与 conda 环境混用)会直接引发 ImportError 或段错误。

NumPy 2.0 的 ABI 变更直接导致旧 C 扩展加载失败
不是“建议更新”,而是二进制层面无法运行:NumPy 2.0 启用了 ABI versioning,隐藏了所有以 _PyArray_ 开头的内部符号(如 _PyArray_Free、_PyArray_Sort),并移除了旧 C API 函数(如 PyArray_GetBuffer)。任何在编译时链接了这些符号的 .so/.pyd 文件,运行时都会报 ImportError: undefined symbol 或 DLL load failed。
PyArray_Descr 结构体改动让内存访问越界
NumPy 2.0 重排了 PyArray_Descr 结构体成员顺序和大小,尤其影响直接读取 itemsize 或 typeobj 的 C 扩展。pybind11 2.11.1 及更早版本硬编码结构体偏移量,升级到 2.12.0 后才改用版本感知的访问逻辑。没升级的扩展一读就崩——不是报错,是段错误(SIGSEGV)。
numpy.import_array() 调用机制被收紧
NumPy 2.0 要求 Cython/C 扩展在模块初始化时必须显式调用 numpy.import_array(),且不能跳过返回值检查。PESQ、noisereduce 等库的旧版扩展常漏掉这步或用错宏(如误写 <void>numpy._import_array</void>),结果触发 ImportError: numpy.core.multiarray failed to import。
构建环境不匹配比代码问题更致命
- conda 环境里用 pip 安装 wheel:pip 拿的是 CI 编译的二进制,可能用 GCC 12 + musl,而 conda 环境是 MSVC/UCRT,DLL 找不到
- 源码编译时
numpy.get_include()指向 NumPy 1.x 头文件,但链接的是 NumPy 2.0 库:编译通过,运行崩溃 - pybind11 版本
真正卡住人的从来不是“要不要改”,而是“改完编译通过,一跑就 segmentation fault”——这时候得查 nm -D your_module.so | grep PyArray,看它到底绑了哪些符号。
立即学习“Python免费学习笔记(深入)”;


















