我使用Python C Api来填充包含PyObject*
元素的列表,并将其传递给Python中的函数。一切都很顺利,但有一个问题 - Python中的转移列表包含奇数<NULL>
个条目。 List也包含“想要的”对象,所以看起来它几乎正在工作。
这是列表预览:
[<NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <dbg.TBack object at 0x19675870>, <interface.Grid object at 0x196758B0>, <interface.Grid object at 0x196758F0>, <interface.slp object at 0x196757D0>]
我用于填写Python C API列表的代码。
PyObject* list = PyList_New(objectsList.size());
PyObject* handle;
for (auto child : objectsList) {
if (!child) {
continue;
}
handle = child->GetHandle(); // handle = PyObject*
if (!handle) {
continue;
}
PyList_Append(list, handle);
}
return list; // push
我尝试添加if(!handle)
项检查,但实际上似乎没有任何结果。
<NULL>
条目? 答案 0 :(得分:2)
if (handle == Py_None) {
continue;
}
或者
int PyObject_Not(PyObject * o)
如果对象o被认为是真,则返回0,否则返回1。这相当于Python表达式而不是o。失败时,返回-1。
否则,也许您可以查看handle
的字符串表示。根据{{3}},您可以使用
int PyObject_Compare(PyObject *o1, PyObject *o2)
PyObject* PyObject_Repr (PyObject *o)
我在想像
这样的东西PyObject* null_str = Py_BuildValue("null_str", "<NULL>");
PyObject* handle_str = PyObject_Repr(handle);
if (!PyObject_Compare(null_str, handle_str)) {
continue;
}
答案 1 :(得分:1)
问题在于如何分配列表。来自PyList_New(Py_ssize_t len)
的{{1}}:
注意:如果len大于零,则返回的列表对象的项目将设置为NULL。因此,在使用
PySequence_SetItem()
将所有项目设置为实际对象之前,不能使用PyList_SetItem()
等抽象API函数或将对象公开给Python代码。
即。它正在制作一个“len
”空指针的列表,而不是制作一个带有预分配空间的空列表。
解决方案是:
len
0)并保持其余代码相同(使用PyList_Append
)或PyList_SetItem
而不是追加。您使用此方法时请注意PyList_setItem
窃取引用(因此您必须incref
handle
),并且您希望列表的长度仅包含getHandle()!=NULL
{1}}。