[英]Obtaining pointer to python memoryview on bytes object
我有一個python memoryview
指向一個bytes
對象,我想在cython中執行一些處理。
我的問題是:
bytes
對象不可寫,所以cython不允許從中構造一個類型化的(cython)內存視圖 例:
在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
幾個警告:
bytes
不可變,如果您嘗試修改內存視圖可能會導致問題 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.