标签: pep3118

在Cython中使用缓冲区API

我正在使用一个C库,它重复调用用户提供的函数指针以获取更多数据.我想以这样的方式,Python实现该回调可以返回任何合理的数据类型写一个用Cython包装一样str,bytearray,内存映射文件等(具体而言,支持缓冲接口).到目前为止我所拥有的是:

from cpython.buffer cimport PyBUF_SIMPLE
from cpython.buffer cimport Py_buffer
from cpython.buffer cimport PyObject_GetBuffer
from cpython.buffer cimport PyBuffer_Release
from libc.string cimport memmove

cdef class _callback:
    cdef public object callback
    cdef public object data

cdef uint16_t GetDataCallback(void * userdata,
                              uint32_t wantlen, unsigned char * data,
                              uint32_t * gotlen):

    cdef Py_buffer gotdata
    box = <_callback> userdata
    gotdata_object = box.callback(box.data, wantlen)
    if not PyObject_CheckBuffer(gotdata_object):
        # sulk
        return 1

    try:
        PyObject_GetBuffer(gotdata_object, &gotdata, PyBUF_SIMPLE)

        if not (0 < gotdata.len <= …
Run Code Online (Sandbox Code Playgroud)

python memory-management cython pybuffer pep3118

21
推荐指数
1
解决办法
2096
查看次数

当使用ctypes数组作为numpy数组时,PEP 3118会发出警告

当我尝试将ctypes数组用作numpy数组时,我收到以下警告消息:

Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes, numpy
>>> TenByteBuffer = ctypes.c_ubyte * 10
>>> a = TenByteBuffer()
>>> b = numpy.ctypeslib.as_array(a)
C:\Python27\lib\site-packages\numpy\ctypeslib.py:402: RuntimeWarning: Item size
computed from the PEP 3118 buffer format string does not match the actual item s
ize.
  return array(obj, copy=False)
>>> b
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=uint8)
Run Code Online (Sandbox Code Playgroud)

但是代码似乎正在起作用.忽略这个警告是不是一个坏主意?

背景:我正在调用一个实时生成数据的C …

python warnings ctypes numpy pep3118

12
推荐指数
2
解决办法
4242
查看次数

当类实现PEP 3118时,Python 2.7中PyBufferProcs的定义

我正在扩展我们的库(支持Python 2.7)中的类以支持PEP 3118,后者已经被反向移植到2.7.

从文档中,我需要初始化tp_as_buffer字段以指向a PyBufferProcs.但是,从2.7的文档中,此结构的描述仅包含旧缓冲区协议的条目.从来源,我收集的是 PyBufferProcs对新协议(一些其他的项目bf_getbufferbf_releasebuffer).

问题仍然存在:

  • 我是否必须做一些特别的事情来告诉Python这些新条目是否有效?

  • 我是否必须填写旧协议的条目?(例如,2.7的文档说明bf_getsegcount 可能不为空.但如果我支持PEP 3118,则不应使用此条目.)

python python-c-api pybuffer python-extensions pep3118

9
推荐指数
1
解决办法
422
查看次数

为什么不能从数组对象中获取Py_buffer?

数组上python文档清楚地表明该数组符合缓冲区接口.它甚至建议不使用buffer_info()方法.但是当我尝试使用PyObject_GetBuffer()从C/C++代码中获取Py_Buffer或使用python的memoryview时,我得到了一个失败.

例如,在python中(我使用的是2.7版):

>>> a = array.array('c')
>>> memoryview(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot make memory view because object does not have the buffer interface
Run Code Online (Sandbox Code Playgroud)

实际上,当我搜索python的代码库时,只有bytearrayobject(bytearray),memoryobject(memoryview)和stringobject(str)在它们上面设置了所需的Py_TPFLAGS_HAVE_NEWBUFFER标志.据我了解,文档是错误的; 数组不支持缓冲区接口.

我可以使用支持缓冲区接口的bytearray,问题是我需要数组的实用fromfile()方法来读取我可以在我的C/C++代码中使用的缓冲区.

有没有一种方法可以让我将文件读入缓冲区并使用C代码中的缓冲区,而不涉及内存副本?(我想处理大二进制文件,复制是一个不太理想的选择).

python arrays buffer memoryview pep3118

6
推荐指数
1
解决办法
2549
查看次数

关于python中的Buffer接口

我对python中的术语'缓冲接口'很困惑.说"暴露其底层内存结构的python对象"可以用某个例子来解释是什么意思.提前谢谢

python pybuffer python-2.7 python-3.x pep3118

6
推荐指数
1
解决办法
1090
查看次数

解析PEP 3118缓冲区协议格式字符串

我对使用缓冲区协议在python,numpy和cython之间传递二进制数据感兴趣。查看PEP 3118,似乎在结构字符串语法中添加了一些内容,从而增加了对诸如命名字段和嵌套结构之类的有用功能的支持。

但是,似乎在这三个位置中,对缓冲区语法的所有范围的支持都受到限制。例如,假设我具有以下cython结构:

ctypedef packed struct ImageComp:
    uint32_t width
    uint32_t height
    uint8_t *pixels

#Here is the appropriate struct format string representation
IMAGE_FORMAT = b'T{L:width:L:height:&B:pixels:}'
Run Code Online (Sandbox Code Playgroud)

尝试如下提取PEP-3118兼容字节字符串

cdef void *image_temp = malloc(sizeof(ImageComp))
IMAGE_SIZE = sizeof(ImageComp)
IMAGE_FORMAT = (<ImageComp[:1]>image_temp)._format
IMAGE_DTYPE = np.asarray(<ImageComp[:1]>image_temp).dtype
free(image_temp)
Run Code Online (Sandbox Code Playgroud)

失败,并显示以下错误消息: Invalid base type for memoryview slice: ImageComp 因为键入的内存视图如果包含指针,则无法创建。

同样,view.array使用我的自定义字符串或使用python struct模块的calcsize函数创建时,会发出类似的警告struct.error: bad char in struct format

我可以Py_buffer按照此处所述手动创建和填充对象,但是尝试将其转换为具有np.asarrayyields 的numpy数组ValueError: 'T{L:width:L:height:&B:pixels:}' is not a valid PEP …

buffer numpy cython python-3.x pep3118

5
推荐指数
0
解决办法
152
查看次数

使用具有不同项目大小的 Py_buffer 和 PyMemoryView_FromBuffer

这个问题与我之前提出的一个问题有关。即这一项,如果有人有兴趣。基本上,我想要做的是使用Py_buffer包装在memoryview-object 中的 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 …
Run Code Online (Sandbox Code Playgroud)

python cpython pybuffer pep3118

5
推荐指数
1
解决办法
4432
查看次数

Cython - 动态 2D C++ 数组的 Memoryview

目标:使用 Cython 从 2D C++ 字符数组获取 Memoryview。

一点背景:

我有一个本机 C++ 库,它生成一些数据并通过 a 返回char**到 Cython 世界。数组在库中的初始化和操作大约是这样的:

struct Result_buffer{
    char** data_pointer;
    int length = 0;

    Result_buffer( int row_capacity) {
        data_pointer; = new char*[row_capacity];
        return arr;
    }

    // the actual data is appended row by row
    void append_row(char* row_data) {
         data_pointer[length] = row_data;
         length++;
    }     
}
Run Code Online (Sandbox Code Playgroud)

所以我们基本上得到了一个嵌套子数组的数组。

旁注:
- 每行具有相同的列数
- 行可以共享内存,即指向相同的 row_data

目标是最好将此数组与内存视图一起使用,而无需昂贵的内存复制。


第一种方法(不起作用)

使用 Cython 数组和内存视图:

这是应该使用生成的数据的 .pyx 文件

from cython cimport view
cimport numpy as np …
Run Code Online (Sandbox Code Playgroud)

python cython pep3118 typed-memory-views

5
推荐指数
1
解决办法
1116
查看次数

PIL Image构造来自numpy数组的怪异图像 - 为什么?

我想要一种方法来生成红色,绿色或蓝色的小RGB方形图像.它应该产生坚固的色块,但PIL输出的图像非常奇怪.为什么?

import numpy as np
from PIL import Image

class MakeSquares():
    def __init__(self):

        self.num_rows = 3
        self.num_cols = 3

        self.colourmap = {'red': [255, 0, 0],
                      'green': [0, 255, 0],
                      'blue': [0, 0, 255]}

    def generateExample(self, label):
        arr = []
        colour = label
        colour_array = self.colourmap[colour]
        for i in range(0, self.num_rows):
            sarr = []
                for j in range(0, self.num_cols):
                    sarr.append(colour_array)
            arr.append(sarr)
        narr = np.asarray(arr)
        return narr

test = MakeSquares()
t = test.generateExample("red")
print t
testimage = Image.fromarray(t, "RGB")
testimage.save("testimage.jpg")
Run Code Online (Sandbox Code Playgroud)

此代码返回以下numpy数组:

[[[255 …
Run Code Online (Sandbox Code Playgroud)

python numpy image python-imaging-library pep3118

3
推荐指数
1
解决办法
1261
查看次数