【发布时间】:2016-09-10 03:28:00
【问题描述】:
我正在尝试在 Python 中创建一个特殊类型的缓冲区,以将其发送到用 CFFI 包装的 C 函数。
在 C 中,我有类似的东西:
typedef unsigned char UINT8;
typedef UINT8* PUINT8;
然后,在 Python 中,以上行在 ffi.cdef() 中,我的缓冲区实例化代码如下所示:
nb_buffer = 8
buffer_size = 42
buffers = ffi.new( "PUINT8[]", nb_buffer )
for i in range( nb_buffer ):
tmp_buffer = ffi.buffer( ffi.new( "UINT8[]", 1 ), buffer_size )
buffers[ i ] = ffi.cast( "PUINT8", ffi.from_buffer( tmp_buffer ) )
c.function( buffers )
C 函数接收一个 UINT8**。
并且...在 C 函数中以更远的分段错误结束。
所以我在使用ffi.cast后print buffers[ i ]:
<cdata 'unsigned char *' 0x2cbaca0>
<cdata 'unsigned char *' 0x2cbacd8>
<cdata 'unsigned char *' 0x2cbaca0>
<cdata 'unsigned char *' 0x2cbacd8>
<cdata 'unsigned char *' 0x2cbaca0>
<cdata 'unsigned char *' 0x2cbacd8>
<cdata 'unsigned char *' 0x2cbaca0>
<cdata 'unsigned char *' 0x2cbacd8>
我错过了什么?缓冲区是否在覆盖tmp_buffer 后立即被垃圾回收?
【问题讨论】:
-
不看细节,但
ffi.buffer( ffi.new( "UINT8[]", 1 ), ... )基本是错的。它的意思是“分配一个数组(一个 UINT8 的);然后为它取一个缓冲区;然后立即忘记新数组,以便立即释放它”。 -
另外,您分配一个 UINT8 的数组,然后将它们视为 42 字节缓冲区。最后 41 个字节无论如何都没有分配。
-
我认为
ffi.buffer()的第一个参数的重要性是 CData 的类型,而不是它的长度(因为它是第二个参数)并且它会以某种方式创建一个给定的 CData 类型给定大小的缓冲区。但我现在明白,第二个参数用于分割比需要更大的内存大小。谢谢阿明!我会尽快尝试你的答案。 -
ffi.buffer()没有分配任何内存,它只是返回现有内存的视图。
标签: python c buffer python-cffi