簡體   English   中英

python 字節 object 底層緩沖區重新分配,cffi

[英]python bytes object underlying buffer reallocation, cffi

我正在使用 python 字節對象將一些數據傳遞給使用 CFFI 庫的本機實現的方法,例如:

from cffi import FFI
ffi = FFI()
lib = ffi.dlopen(libname)
ffi.cdef("""
    void foo(char*);
""")
x = b'abc123'
lib.foo(x)

據我了解,本機方法接收的指針是x字節object后面的實際底層緩沖區的指針。 這在 99% 的情況下都可以正常工作,但有時指針似乎變得無效並且它指向的數據包含垃圾,在本機調用完成后的一段時間 - 本機代碼在從初始調用返回后保留指針並期望要存在的數據,並且 python 代碼確保保留對 x 的引用,以便指針希望保持有效。

在這些情況下,如果我再次調用具有相同字節 object 的本機方法,我可以看到我得到一個指向相同值但位於不同地址的不同指針,這表明字節 object 后面的底層緩沖區已移動(如果我關於 CFFI 提取指向由字節 object 包含的底層數組的指針的假設是正確的,並且沒有在任何地方創建臨時副本),盡管據我所知,字節 object 沒有以任何方式修改(代碼是大型代碼庫的一部分,但我有理由確定字節對象不會被代碼直接修改)。

這里會發生什么? 我對 CFFI 獲得指向字節 object 的實際內部緩沖區的指針的假設是否不正確? 是否允許 python 靜默重新分配字節對象后面的緩沖區以進行垃圾收集/ memory 壓縮原因,這是否不知道我持有指向它的指針? 我正在使用 pypy 而不是默認的 python 解釋器,如果這有區別的話。

你的猜測是正確的答案。 (記錄的)保證只是在這種情況下傳遞的指針在調用期間有效。

PyPy 的垃圾收集器可以移動 memory 中的對象,如果它們足夠小,那么這樣做可以提高整體性能。 但是,在執行這樣的 cffi 調用時,pypy 通常會在調用期間將 object 標記為“固定”(除非固定對象已經太多並且添加更多會嚴重影響未來的 GC 性能;在這種罕見的情況下,它會無論如何都要復制一份,然后釋放它)。

如果您的 C 代碼需要在調用返回后訪問 memory,您必須明確地制作一個副本,例如使用 ffi.new("char[]", mybytes),並根據需要保持其活動狀態。

暫無
暫無

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

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