编辑:在重新阅读我原来的问题后,我很快意识到它的措辞非常糟糕,含糊不清,而且太令人困惑,无法得到一个像样的答案。这就是我在午休结束时匆忙提出问题所得到的结果。希望这会更清楚:

我试图将一个简单的 C 结构作为 PyBuffer 公开给 Python (3.x),以便我可以从中检索 MemoryView。我想要公开的结构与此类似:

struct ImageBuffer {
    void* bytes;
    int row_count;
    int bytes_per_row;
};

我希望允许脚本编写者像这样访问数据:

img_buffer = img.get_buffer()
img_buffer[1::4] = 255 # Set every Red component to full intensity

不幸的是,关于这些结构的 C API 的现有文档非常稀疏,有些地方自相矛盾,而其他地方则完全错误(记录的函数签名与标头中的签名不匹配等)。因此,我没有一个很好的文档。关于如何最好地揭露这一点的想法。另外,我想避免包含第三方库来实现应该成为核心库一部分的功能,但在我看来,PyBuffer 功能仍然相当不成熟,也许像 NumPy 这样的东西会是更好的选择。

有人对此有什么建议吗?

有帮助吗?

解决方案

此处描述了要实现的一组方法,以便您的扩展类型支持缓冲区协议: http://docs.python.org/3.1/c-api/typeobj.html#buffer-object-structs

我认识到该文档相当粗糙,因此我能给出的最佳建议是从 C 类型的缓冲区 API 的现有实现开始,例如官方 Python 源代码中的 bytesobject.c 或 bytearrayobject.c。

但是,请注意,缓冲区协议不允许访问高级符号,例如您引用的符号: img_buffer[1::4] = 255 不适用于内存视图对象。

编辑: 更准确地说,内存视图支持某些类型的切片分配,但不是全部。此外,它们还不够“聪明”,无法理解将 255 分配给切片实际上意味着您希望重复该字节值。例子:

>>> b = bytearray(b"abcd")
>>> m = memoryview(b)
>>> m[0:2] = b"xy"
>>> b
bytearray(b'xycd')
>>> m[0:2] = 255
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'int' does not support the buffer interface
>>> m[0:2] = b"x"
Traceback (most recent call last):
  File "", line 1, in 
ValueError: cannot modify size of memoryview object
>>> m[0::2] = b"xy"
Traceback (most recent call last):
  File "", line 1, in 
NotImplementedError
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top