簡體   English   中英

在bytes對象上獲取指向python memoryview的指針

[英]Obtaining pointer to python memoryview on bytes object

我有一個python memoryview指向一個bytes對象,我想在cython中執行一些處理。

我的問題是:

  • 因為bytes對象不可寫,所以cython不允許從中構造一個類型化的(cython)內存視圖
  • 我也不能使用指針,因為我無法獲得指向memoryview start的指針

例:

在python中:

array = memoryview(b'abcdef')[3:]

在cython中:

  • cdef char * my_ptr = &array[0]無法使用以下消息進行編譯: Cannot take address of Python variable
  • cdef char[:] my_view = array在運行時因消息失敗: BufferError: memoryview: underlying buffer is not writable

如何解決這個問題?

好吧,在挖掘了python api之后,我找到了一個解決方案來獲取指向memoryview中的bytes對象緩沖區的指針(這里稱為bytes_view = memoryview(bytes()) )。 也許這有助於其他人:

from cpython.buffer cimport PyObject_GetBuffer, PyBuffer_Release, PyBUF_ANY_CONTIGUOUS, PyBUF_SIMPLE


cdef Py_buffer buffer
cdef char * my_ptr

PyObject_GetBuffer(bytes, &buffer, PyBUF_SIMPLE | PyBUF_ANY_CONTIGUOUS)
try:
    my_ptr = <char *>buffer.buf
    # use my_ptr
finally:
    PyBuffer_Release(&buffer)

您可以使用bytearray創建可變的內存視圖。 請注意,這不會更改字符串,只會更改bytearray

data = bytearray('python')
view = memoryview(data)
view[0] = 'c'
print data
# cython

使用bytearray (根據@ CheeseLover的答案)可能是正確的做事方式。 我的建議是完全使用bytearrays工作,從而避免臨時轉換。 然而:

char*可以直接從Python字符串 (或bytes )創建 - 請參閱鏈接部分的結尾:

cdef char * my_ptr = array
# you can then convert to a memoryview as normal in Cython
cdef char[:] mview = <char[:len(array)]>my_ptr

幾個警告:

  1. 請記住, bytes不可變,如果您嘗試修改內存視圖可能會導致問題
  2. my_ptr (以及mview )只有在array有效時才有效,所以只要你需要訪問數據,一定要保持對array的引用,

如果您不希望cython memoryview失敗並且“底層緩沖區不可寫”,那么您根本不應該要求可寫緩沖區。 一旦你進入C域,你可以簡單地處理那個可寫性。 這樣可行:

cdef const unsigned char[:] my_view = array
cdef char* my_ptr = <char*>&my_view[0]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM