C++程序导入Python文件遇ModuleNotFoundError问题求助
解决方案
问题根源
出现ModuleNotFoundError的核心原因有两个:
- 你添加到
sys.path的空字符串对应程序运行时的工作目录,而非multiset_bell_numbers.py所在的prog源码目录(比如用CMake编译后,默认在build目录运行,此时工作目录不是源码目录)。 - 模块导入时的字符串处理错误,不应带
.py后缀,且需用正确的API创建模块名字符串。
具体修改步骤
1. 修正模块导入的字符串处理
直接用模块名(不带.py后缀)创建字符串对象,替换原代码中的模块字符串生成逻辑:
// 替换原myModuleString的创建代码 PyObject* myModuleString = PyUnicode_FromString("multiset_bell_numbers");
2. 正确添加模块所在目录到sys.path
推荐使用获取可执行文件所在目录的方法,确保无论程序在哪运行都能找到模块:
#include <Python.h> #include <stdexcept> #include <filesystem> // C++17及以上版本支持 int main(int argc, char *argv[]){ Py_Initialize(); // 添加模块所在目录到sys.path PyObject* sys = PyImport_ImportModule("sys"); PyObject* path = PyObject_GetAttrString(sys, "path"); // 获取当前可执行文件的所在目录 std::string exe_dir = std::filesystem::canonical(std::filesystem::path(argv[0])).parent_path().string(); PyObject* module_dir = PyUnicode_FromString(exe_dir.c_str()); PyList_Append(path, module_dir); // 释放临时对象,避免内存泄漏 Py_DECREF(module_dir); Py_DECREF(path); Py_DECREF(sys); // 导入模块 PyObject* myModuleString = PyUnicode_FromString("multiset_bell_numbers"); PyObject *pModule = PyImport_Import(myModuleString); if (pModule == nullptr) { PyErr_Print(); throw std::runtime_error("pModule is empty"); } // 后续调用模块函数的逻辑... // 清理资源 Py_DECREF(myModuleString); Py_DECREF(pModule); Py_Finalize(); return 0; }
如果是Windows系统,替换获取目录的代码为:
#include <Windows.h> // ... wchar_t exe_path[MAX_PATH]; GetModuleFileNameW(NULL, exe_path, MAX_PATH); std::wstring exe_dir = std::filesystem::path(exe_path).parent_path().wstring(); PyObject* module_dir = PyUnicode_FromWideString(exe_dir.c_str(), exe_dir.size());
3. 额外注意事项
- 确保
sympy已安装到CMake检测到的Python环境中:运行pip install sympy(如果使用虚拟环境,需先激活对应环境)。 - 调试阶段可直接添加固定的源码目录路径(适合快速验证):
PyObject* module_dir = PyUnicode_FromString("/你的/prog目录绝对路径");
内容的提问来源于stack exchange,提问作者linuxbeginner
相关产品推荐
相关产品推荐

