我在 C++ 中使用 python 的 C API (2.7) 将 python 树结构转换为 C++ 树。代码如下:
python 树被递归地实现为具有子列表的类。叶节点只是原始整数(不是类实例)
我加载一个模块并从 C++ 调用一个 python 方法,使用来自here的代码,它返回树的一个实例,python_tree,作为 C++ 中的 PyObject。
递归遍历得到的PyObject。要获得孩子的名单,我这样做:
PyObject* attr = PyString_FromString("children"); PyObject* list = PyObject_GetAttr(python_tree,attr); for (int i=0; i<PyList_Size(list); i++) { PyObject* child = PyList_GetItem(list,i); ...
非常简单,它可以工作,直到我最终在调用 PyObject_GetAttr 时遇到分段错误(Objects/object.c:1193,但我看不到 API 代码)。它似乎发生在访问树的最后一个叶子节点时。
我很难确定问题所在。使用 C API 进行递归是否有任何特殊注意事项?我不确定我是否需要使用 Py_INCREF/Py_DECREF,或者使用这些函数或其他东西。老实说,我并不完全理解 API 的工作原理。任何帮助深表感谢!
编辑:一些最小的代码:
void VisitTree(PyObject* py_tree) throw (Python_exception)
{
PyObject* attr = PyString_FromString("children");
if (PyObject_HasAttr(py_tree, attr)) // segfault on last visit
{
PyObject* list = PyObject_GetAttr(py_tree,attr);
if (list)
{
int size = PyList_Size(list);
for (int i=0; i<size; i++)
{
PyObject* py_child = PyList_GetItem(list,i);
PyObject *cls = PyString_FromString("ExpressionTree");
// check if child is class instance or number (terminal)
if (PyInt_Check(py_child) || PyLong_Check(py_child) || PyString_Check(py_child))
;// terminal - do nothing for now
else if (PyObject_IsInstance(py_child, cls))
VisitTree(py_child);
else
throw Python_exception("unrecognized object from python");
}
}
}
}