Python C Api 将 PyObject * 传输到 c 数组中

Posted

技术标签:

【中文标题】Python C Api 将 PyObject * 传输到 c 数组中【英文标题】:Python C Api transfer a PyObject * into c array 【发布时间】:2016-02-01 22:42:13 【问题描述】:

我使用了 python c api 并希望从 python 中获取一个数组。我从 python 端返回了一个 python 数组,并希望将 PyObject* 结果传输到一个 c 数组中以便我可以使用它。

有没有我能做到的?

附带问题:在什么情况下尝试返回数组中的元素,例如

return arr[3]

会导致 PyObject_callobject 返回 NULL 吗?

return arr

确实给了我一些东西

【问题讨论】:

当你说你想将PyObject *结果转换成一个C数组时,你的意思是PyObject *的C数组还是你想把那些数组成员对象转换成更原生的C也代表? @KenClement 我可能也会这么说。如果我没记错的话,我可以使用 Pystring_fromstring 单独翻译它的成员。在旁注中,当我在 python 中执行 type(arr[3]) 时,它告诉我它是 unicode。这对字符串有什么影响吗? 您在使用Pystring_fromstring 方面走在正确的轨道上,但您使用的 Python 版本(2.7 或 3.5)确实很重要。 (另外,我可能应该问您使用的是 CPython 还是 IronPython 还是 PyPy - 我从您的评论中猜测它是 CPython)2.7 和 3.5 之间的差异将决定 unicode 是否与 str 有所不同。在 CPython 2.7 str 通常处理窄字符数据 - 而不是 unicode。在 3.5 中,这种区别已被删除(所有字符串都是 unicode)。 API 在这方面不兼容。你是哪个版本的? 【参考方案1】:

在 Python 中,“数组”是 list 数据类型。查看 C API 中的 PyList_* 函数。您可以找到此参考资料here for 2.7 和here for 3.5。感兴趣的函数是:

Py_ssize_t PyList_Size(PyObject *list)获取列表成员数量 和 PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index) 获取对该索引处成员的引用。

简单地使用malloc 或类似的分配器和for 循环就可以解决问题。

另请注意,仅涉及借用引用,因此无需通过void Py_INCREF(PyObject *o)void Py_DECREF(PyObject *o) 维护这些对象的引用计数。

【讨论】:

以上是关于Python C Api 将 PyObject * 传输到 c 数组中的主要内容,如果未能解决你的问题,请参考以下文章

迁移到 numpy api 1.7

从 C 函数构建 PyObject*?

为啥 PyObject_Print 会崩溃?

在 C++ 中的 PyObject 上调用 `+=`

Python C API - 创建关键字

在 Python 的 C/C++ 扩展中,返回的 PyObject* 应该有多少引用计数?