在C++中通过CPython嵌入Python代码时无法导入Numpy的问题求助
我最近在开发一个用CMake构建的C应用,核心需求是嵌入Python脚本——由C负责初始化数据、传递给Python脚本处理,最后取回计算结果。但运行程序时直接碰到了报错:
ModuleNotFoundError: No module named 'numpy.core._multiarray_umath'
我使用的是CPython 3.10版本,搭配Numpy 1.25.0。已经尝试过更新Numpy,但问题依旧;后来换用pybind11尝试,结果导入Numpy时还是出现类似问题。有没有大佬能给点解决思路?
附上我的配置信息:
我的CMakeLists.txt内容如下:
set(PYTHON_DIR ${PYTHON_DIRECTORY}) find_package(Python3 COMPONENTS Interpreter NumPy Development REQUIRED) include_directories(${PYTHON_DIR}/include) link_directories(${PYTHON_DIR}/libs) add_executable(cpython "main.cpp" "main.h" "pyhelper.h") target_link_libraries(cpython PUBLIC Python3::NumPy)
另外在CMakePresets.json里已经指定了PYTHON_DIRECTORY的路径。
给你几个排查方向和解决方案,都是嵌入Python+Numpy时常见的坑:
先确认Python环境的一致性
你CMake指定的PYTHON_DIRECTORY对应的Python环境,真的安装了正确版本的Numpy吗?很多人电脑里同时存在多个Python版本(系统自带、conda、手动安装的),很容易搞混环境。- 直接打开这个PYTHON_DIRECTORY下的
python.exe(Windows)或python3(Linux/macOS),输入import numpy试试,如果这里都报错,那就是这个环境的Numpy要么没装,要么损坏了。可以直接重装:pip install --force-reinstall numpy==1.25.0 - 检查这个环境的
Lib/site-packages文件夹里有没有numpy目录,里面有没有core/_multiarray_umath.*这类文件(Windows下是.pyd,Linux是.so),如果缺失就是安装出了问题。
- 直接打开这个PYTHON_DIRECTORY下的
优化你的CMake配置
你现在手动添加了include_directories和link_directories,但其实find_package(Python3)已经帮你处理了这些路径,手动指定反而可能导致冲突。建议调整如下:- 删掉这两行冗余配置:
include_directories(${PYTHON_DIR}/include) link_directories(${PYTHON_DIR}/libs) - 链接时加上基础的Python库,因为嵌入CPython必须依赖它:
target_link_libraries(cpython PUBLIC Python3::Python Python3::NumPy) - CMake配置时留意输出日志,确认
Python3_FOUND、Python3_NumPy_FOUND都是TRUE,且显示的路径和你指定的PYTHON_DIRECTORY一致,避免find_package误找了其他Python环境。
- 删掉这两行冗余配置:
运行时手动设置PYTHONPATH
有时候C++程序运行时,Python找不到site-packages的路径,导致识别不了Numpy。可以手动指定路径:- Windows下,运行程序前先执行:
set PYTHONPATH=你的PYTHON_DIRECTORY\Lib\site-packages - Linux/macOS下:
export PYTHONPATH=你的PYTHON_DIRECTORY/Lib/site-packages - 也可以在C++初始化Python的代码里手动添加路径,这样不用每次运行都设置环境变量:
#include <Python.h> // ... Py_Initialize(); // 替换成你实际的site-packages路径 std::string sitePackages = "你的PYTHON_DIRECTORY/Lib/site-packages"; PyRun_SimpleString(("import sys; sys.path.insert(0, '" + sitePackages + "')").c_str());
- Windows下,运行程序前先执行:
避免手动编译Numpy(如果之前这么做了)
要是你是手动编译的Numpy,很可能没把_multiarray_umath这个核心扩展模块编译完整。建议直接用pip安装官方预编译的轮子,省心又不容易出依赖问题。
备注:内容来源于stack exchange,提问作者am_289

