我想使用python.h在C ++中调用Python函数,但是存在一些问题。
这是我的Python函数示例
def function1(tuple1, tuple2, string1, string2 ,string3, double1, string4 = ""):
...
和C ++示例
double function_adapter(const vector<double> &vec1, const vector<double> &vec2, const string &string1, const string &string2, const string &string3, const double double1, const string &string4)
{
Py_Initial();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append(\"./\")");
PyObject *pModule, *pFunc, *pRes;
pModule = PyImport_Import(PyString_FromString("PythonFile"));
pFunc = PyObject_GetAttrString(pModule, "function1");
PyObject *pArgs = PyTuple_New(7);
PyObject *pVec1 = PyTuple_New(vec1.size());
for(size_t i = 0; i < vec1.size(); ++i) {
PyTuple_SetItem(pVec1, i, Py_BuildValue("f", vec1[i]));
}
PyObject *pVec2 = PyTuple_New(vec2.size());
for(size_t i = 0; i < vec2.size(); ++i) {
PyTuple_SetItem(pVec2, i, Py_BuildValue("f", vec2[i]));
}
PyObject *pString1 = Py_BuildValue("s", string1);
PyObject *pString2 = Py_BuildValue("s", string2);
PyObject *pString3 = Py_BuildValue("s", string3);
PyObject *pDouble1 = Py_BuildValue("f", double1);
PyObject *pString4 = Py_BuildValue("s", string4);
PyTuple_SetItem(pArgs, 0, pVec1);
PyTuple_SetItem(pArgs, 1, pVec2);
PyTuple_SetItem(pArgs, 2, pString1);
PyTuple_SetItem(pArgs, 3, pString2);
PyTuple_SetItem(pArgs, 4, pString3);
PyTuple_SetItem(pArgs, 5, pDouble1);
PyTuple_SetItem(pArgs, 6, pString4);
pRes = PyObject_CallObject(pFunc, pArgs);
if(pRes == NULL) {
return -2;
}
int res = PyLong_AsLong(pRes);
Py_DecRef(pModule);
.
.
.
Py_Finalize();
return res;
}
但是pRes返回NULL。 PyObject_CallObject就像一个黑匣子,我无法介入以了解其工作原理。
所以我想问我的代码有什么问题吗?
论点准备是否正确? (在这种情况下,互联网上的例子很少。)
答案 0 :(得分:2)
返回NULL的CPython API函数表示已发生错误。您可以使用PyErr_*
组API函数来查询此异常。
对于调试而言,最有用的可能是PyErr_Print()
,它只会将异常和堆栈跟踪(如果有)打印到stderr。
请确保再次检查pModule
和pFunc
是否为NULL。尝试导入模块或从模块获取功能时可能发生了异常。 CPython不会引发异常,它只会在发生错误时返回NULL。因此,检查C-API函数的返回值很重要。