我有一些代码将转到目录(文件夹1用于演示目的),然后在文件function
中调用名为python_function.py
的函数。代码如下所示:
#include <Python.h>
#include <string>
#include <iostream>
int main()
{
PyObject *pName, *pModule, *pDict, *pFunc;
setenv("PYTHONDONTWRITEBYTECODE", " ", 1);
// Initialize the Python Interpreter
Py_Initialize();
//CALL FUNCTION FROM FOLDER 1:
std::wstring pathWide = L"./Folder 1";
PySys_SetPath(pathWide.c_str());
// Build the name object
pName = PyUnicode_FromString((char*)"python_function");
// Load the module object
pModule = PyImport_Import(pName);
// pDict is a borrowed reference
pDict = PyModule_GetDict(pModule);
// pFunc is also a borrowed reference
pFunc = PyDict_GetItemString(pDict, (char*)"function");
if (pFunc != NULL)
{
if (PyCallable_Check(pFunc))
{
PyObject *pResult;
pResult = PyObject_CallFunction(pFunc, "");
Py_DECREF(pResult);
}
else {PyErr_Print();}
}
else {std::cout << "pFunc is NULL!" << std::endl;}
// Clean up
Py_DECREF(pFunc);
Py_DECREF(pDict);
Py_DECREF(pModule);
Py_DECREF(pName);
// Finish the Python Interpreter
Py_Finalize();
return 0;
}
此代码在我的系统上编译并完美运行,但是只要我想在第二个目录中调用另一个函数,称为文件夹2,我就会收到错误:Segmentation Fault (core dumped)
。这是代码:
#include <Python.h>
#include <string>
#include <iostream>
int main()
{
PyObject *pName, *pModule, *pDict, *pFunc;
setenv("PYTHONDONTWRITEBYTECODE", " ", 1);
// Initialize the Python Interpreter
Py_Initialize();
//CALL FUNCTION FROM FOLDER 1:
std::wstring pathWide = L"./Folder 1";
PySys_SetPath(pathWide.c_str());
// Build the name object
pName = PyUnicode_FromString((char*)"python_function");
// Load the module object
pModule = PyImport_Import(pName);
// pDict is a borrowed reference
pDict = PyModule_GetDict(pModule);
// pFunc is also a borrowed reference
pFunc = PyDict_GetItemString(pDict, (char*)"function");
if (pFunc != NULL)
{
if (PyCallable_Check(pFunc))
{
PyObject *pResult;
pResult = PyObject_CallFunction(pFunc, "");
Py_DECREF(pResult);
}
else {PyErr_Print();}
}
else {std::cout << "pFunc is NULL!" << std::endl;}
//CALL FUNCTION FROM FOLDER 2:
pathWide = L"./Folder 2";
PySys_SetPath(pathWide.c_str());
// Build the name object
pName = PyUnicode_FromString((char*)"python_function");
// Load the module object
pModule = PyImport_Import(pName);
// pDict is a borrowed reference
pDict = PyModule_GetDict(pModule);
// pFunc is also a borrowed reference
pFunc = PyDict_GetItemString(pDict, (char*)"function");
if (pFunc != NULL)
{
if (PyCallable_Check(pFunc))
{
PyObject *pResult;
pResult = PyObject_CallFunction(pFunc, "");
Py_DECREF(pResult);
}
else {PyErr_Print();}
}
else {std::cout << "pFunc is NULL!" << std::endl;}
// Clean up
Py_DECREF(pFunc);
Py_DECREF(pDict);
Py_DECREF(pModule);
Py_DECREF(pName);
// Finish the Python Interpreter
Py_Finalize();
return 0;
}
我调用第一个函数后发生错误,所以它似乎没有更改目录或其他东西。我使用的是Ubuntu,我有python 3.4
我尝试了其他更改目录的方法,不只是PySys_SetPath
,还有setenv("PYTHONPATH", path, 1);
注意:我现在不担心错误检测,我宁愿让代码在理想情况下工作,然后担心不完美的环境。
编辑:
调试输出:
#0 0x7ffff79b16cb PyModule_GetDict() (/usr/lib/x86_64-linux-gnu/libpython3.4m.so.1.0:??)
#1 0x4010e6 main() (/home/ben/Documents/Programming/Projects/PYTHON TEST/main.cpp:23)
奇怪的是调试说错误发生在第23行,但如果你运行第一个代码段,第23行不会导致错误
对PETER BRITTAIN&#39; ANSWER的反应:
如果我用PyImport_Import()
替换第二个PyImport_ReloadModule()
,我会在控制台上输出错误,如下所示:
ImportError: No module named 'imp'
Error in sys.excepthook:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/apport_python_hook.py", line 53, in apport_excepthook
if not enabled():
File "/usr/lib/python3/dist-packages/apport_python_hook.py", line 24, in enabled
import re
ImportError: No module named 're'
Original exception was:
ImportError: No module named 'imp'
答案 0 :(得分:4)
编辑:更新了发现的错误的进一步答案。
您未能在调试输出中导入模块。在调试器外部运行时,您会遇到无法使用相同的导入调用导入的问题。完整的问题链是这样的。
调试时:
PySys_SetPath()
接受。PyImport_Import()
获取NULL,表示导入失败(在调试器下记录为here。我遇到了Python2.7的问题(使用char *而不是wchar * - 如下面的评论中所述)。正常运行时将其放在一边:
PySys_SetPath()
接受。PyImport_ReloadModule()
代替。所以,修正是:
std::string
代替std::wstring
(对于Python 2.x)。PyImport_ReloadModule()
。PyErr_Print()
显式模块导入错误。