【问题标题】:Create a CData-typed buffer in Python with CFFI使用 CFFI 在 Python 中创建 CData 类型的缓冲区
【发布时间】: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.castprint 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


【解决方案1】:

使用列表推导:

keepalive = [ ffi.new( "UINT8[]", buffer_size ) for i in range( nb_buffer ) ]
buffers = ffi.new( "PUINT8[]", keepalive )

c.functions( buffers )

# keepalive stays alive at least until here

【讨论】:

    【解决方案2】:

    怎么样:

    buffers = ffi.new( "PUINT8[]", nb_buffer )
    keepalive = []
    
    for i in range( nb_buffer ):
        p = ffi.new("UINT8[]", buffer_size)
        keepalive.append(p)
        buffers[i] = p
    
    c.function( buffers )
    
    # keepalive stays alive at least until here
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-23
      • 1970-01-01
      • 2015-12-27
      • 1970-01-01
      • 2016-07-02
      • 1970-01-01
      • 2011-03-26
      • 1970-01-01
      相关资源
      最近更新 更多