gpt4 book ai didi

python - 将 C++ 缓冲区复制到 Python 的最佳方法

转载 作者:太空宇宙 更新时间:2023-11-04 07:10:48 24 4
gpt4 key购买 nike

在使用 Python 处理 C 扩展时,将数据从 C++ 数组或 vector 移动到 PyObject/PyList 的最佳方法是什么> 所以它可以返回给 Python?

我现在使用的方法似乎有点笨拙。我遍历每个元素并调用 Py_BuildValue 将值附加到 PyList

有没有类似memcpy的东西?

最佳答案

如果您的 vector 包含同质数值数据,那么您最好创建一个 array.array将值传输到 Python。

与列表不同,数组在内部将其值存储为原生 C 值的连续数组,但在其他方面提供了一个类似 Pythonic 列表的接口(interface)。它使用最大限度地减少内存占用,并使您能够实际使用单个 memcpy 调用来有效地传输数据。这是一个例子:

PyObject *
vec_to_array(std::vector<double>& vec)
{
static PyObject *single_array;
if (!single_array) {
PyObject *array_module = PyImport_ImportModule("array");
if (!array_module)
return NULL;
PyObject *array_type = PyObject_GetAttrString(array_module, "array");
Py_DECREF(array_module);
if (!array_type)
return NULL;
// array.array('d', [0.0])
single_array = PyObject_CallFunction(array_type, "c[d]", 'd', 0.0);
Py_DECREF(array_type);
if (!single_array)
return NULL;
}

// extra-fast way to create an empty array of count elements:
// array = single_element_array * count
PyObject *pysize = PyLong_FromSsize_t(vec.size());
if (!pysize)
return NULL;
PyObject *array = PyNumber_Multiply(single_array, pysize);
Py_DECREF(pysize);
if (!array)
return NULL;

// now, obtain the address of the array's buffer
PyObject *buffer_info = PyObject_CallMethod(array, "buffer_info", "");
if (!buffer_info) {
Py_DECREF(array);
return NULL;
}
PyObject *pyaddr = PyTuple_GetItem(buffer_info, 0);
void *addr = PyLong_AsVoidPtr(pyaddr);

// and, finally, copy the data.
if (vec.size())
memcpy(addr, &vec[0], vec.size() * sizeof(double));

return array;
}

通过模板特化来增强它以支持其他原始类型留给读者作为练习。

关于python - 将 C++ 缓冲区复制到 Python 的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28560045/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com