从 C++ 修改 python 列表

Posted

技术标签:

【中文标题】从 C++ 修改 python 列表【英文标题】:modify a python list from C++ 【发布时间】:2013-04-05 12:15:05 【问题描述】:

我有一个 Python 列表,我可以获取它的指针并将这个指针地址传递给 C++ 来处理

MyPointer = TheList.as_pointer()

现在我使用 ctypes 将此地址传递给 C++

在 C++ 中,我可以执行以下操作:

*(float*) MyPointer = 2.0f; //for example

并且 Python 值会立即更新,现在的问题是: 如何扩展或删除一些值(如直接从 C++ 修改列表) 因为我感觉这些数据是 std::vector 如何做 push_back 等等以快速方式调整大小(因为在 Python 中迭代非常慢)

【问题讨论】:

as_pointer 似乎是 Blender 特定的,据我所见……无论如何,Python list not 实现为 std::vector,它是一个自己的数据结构体。您需要将指针转换为该数据类型才能使用它。类型在Python C API中定义。 当您想使用 Python C-API 时,最好实际编写 C 扩展模块而不是使用 ctypes,请参阅 docs.python.org/2.7/extending/index.html 和 docs.python.org/2.7/c-api/list.html @KonradRudolph 确实来自 Blender Python api :) 如果您需要快速迭代,您可能希望使用array.array('d')numpy.array。它们允许将浮点数有效地打包到数组中。另一方面,Python 列表包含(在 C++ 术语中)指向堆栈分配对象的指针,每个对象都包含一个双精度。 IE。这就像一个std::vector<PyObject*>,其中每个PyObject* 必须被取消引用才能到达底层double。要将单个数字附加到 Python 列表中,您必须对其进行堆分配以获取 PyObject* 【参考方案1】:

仅给定该指针,您无法扩展列表。您传递给 C++ 的是内部用于实现 Python 列表的 array 的地址。这不能是std::vector,因为 Python 列表不是作为 STL 向量实现的,而是作为 Python 对象引用的 C 级数组实现的。这些数组不包含指向 Python 列表对象的反向指针。

要更改列表,请查看the documentation 并将您的 C++ 代码与 Python 库链接。如果您确实必须从 ctypes 调用您的 C++ 函数,请使用列表的 id 调用它以获取指向列表的指针,而不是其元素数组。然后就可以像这样对列表进行操作:

#include <Python.h>

extern "C"
void append_to_list(uintptr_t lst_id)

    PyObject* lst = reinterpret_cast<PyObject*>(ptr);
    PyObject* new_num = PyFloat_FromDouble(2.0);
    if (!new_num) 
        ... PyFloat creation failed ...
    
    int ret = PyList_Append(lst, new_num);
    Py_DECREF(new_num);
    if (ret) 
        ... PyList_Append failed ...
    

【讨论】:

我理解这个概念,但是在 python 中执行时它给了我一个内存错误:在 0x000 读取访问冲突 PyList_Append 失败 没有进行错误检查,但是在每一行之后做了 printf 并且在 PyList_Append 之后没有打印 好吧,我没有检查值(但我知道错误是否会从 python 文档中生成 -1),因为我找到了一种在没有 PyObjects 的情况下工作的更好方法(我讨厌它们:D)一个浮点指针并使用它 ^_^ 仍然会尝试修改它的大小(还不知道如何)

以上是关于从 C++ 修改 python 列表的主要内容,如果未能解决你的问题,请参考以下文章

从 C++ 调用的 python 方法返回列表

使用 c++ boost::python 从 python 函数返回的列表中获取数据?

如何通过 ctypes 将(非空)列表从 Python 传递到 C++?

SWIG:将其参数从 c++ 修改为 python 的函数

python 从入门到放弃之列表的增加,删除,插入,修改

使用 swig 类型映射从 c++ 方法返回向量<pair<int,int>> & 到 python 元组列表