【发布时间】:2013-03-06 10:05:43
【问题描述】:
这个问题与我之前提出的问题有关。即this one,如果有人感兴趣的话。基本上,我想做的是使用包装在memoryview-object 中的Py_buffer 将C 数组公开给Python。我已经使用PyBuffer_FillInfo 让它工作(工作 = 我可以在 Python 中操作数据并将其写入 C 中的标准输出),但是如果我尝试滚动我自己的缓冲区,我会得到一个段错误之后 C 函数返回。
我需要创建自己的缓冲区,因为 PyBuffer_FillInfo 假定格式为 char,使 itemsize 字段为 1。我需要能够提供大小为 1、2、4 和 8 的项目。
一些代码,这是一个工作示例:
Py_buffer *buf = (Py_buffer *) malloc(sizeof(*buf));
int r = PyBuffer_FillInfo(buf, NULL, malloc(sizeof(char) * 4), 4, 0, PyBUF_CONTIG);
PyObject *mv = PyMemoryView_FromBuffer(buf);
//Pack the memoryview object into an argument list and call the Python function
for (blah)
printf("%c\n", *buf->buf++); //this prints the values i set in the Python function
查看PyBuffer_FillInfo的实现,真的很简单,我滚动了自己的函数来提供自定义项目大小:
//buffer creation function
Py_buffer *getReadWriteBuffer(int nitems, int itemsize, char *fmt) {
Py_buffer *buf = (Py_buffer *) malloc(sizeof(*buf));
buf->obj = NULL
buf->buf = malloc(nitems * itemsize);
buf->len = nitems * itemsize;
buf->readonly = 0;
buf->itemsize = itemsize;
buf->format = fmt;
buf->ndim = 1;
buf->shape = NULL;
buf->strides = NULL;
buf->suboffsets = NULL;
buf->internal = NULL;
return buf;
}
我如何使用它:
Py_buffer *buf = getReadWriteBuffer(32, 2, "h");
PyObject *mv = PyMemoryView_FromBuffer(buf);
// pack the memoryview into an argument list and call the Python function as before
for (blah)
printf("%d\n", *buf->buf); //this prints all zeroes even though i modify the array in Python
return 0;
//the segfault happens somewhere after here
使用我自己的缓冲区对象的结果是C函数返回后的段错误。我真的不明白为什么会发生这种情况。任何帮助将不胜感激。
编辑
根据我之前未能找到的this question,甚至可能根本不支持 itemsize > 1。这使得这个问题更加有趣。也许我可以使用 PyBuffer_FillInfo 和足够大的内存块来保存我想要的东西(例如 32 个 C 浮点数)。在这种情况下,问题更多是关于如何将 Python 浮点数分配给 Python 函数中的 memoryview 对象。问题问题。
【问题讨论】:
-
如果
Py_buffermalloc'ed 存在内存泄漏。使用分配的堆栈Py_buffer
标签: python cpython pybuffer pep3118