将ctype字节数组转换为字节

时间:2013-03-13 04:53:11

标签: python-2.7 ctypes

我有一个我这样定义的ctypes数组:

buff= (c_ubyte*buff_size)()

用数据填充缓冲区后,我需要以字节格式存储这些数据。现在我正按以下方式进行:

buff= [n for n in buff]
buff = ''.join(map(chr, buff))

这个问题是它将它转换为4字节(或任意数量的字节)int,然后再将其转换回单字节字符串,这会浪费大量的CPU。

如何直接将ctypes缓冲区转换为字节?我不是想保存自己的副本,因为我无论如何都要做副本,因为我无法保留原始缓冲区。 python是否有针对此类内容的强制转换功能?

感谢。

1 个答案:

答案 0 :(得分:15)

如果您确实需要副本,可以使用bytearray

>>> buff = (c_ubyte * 4)(*[97,98,99,100])
>>> bs = bytearray(buff)
>>> bs
bytearray(b'abcd')
>>> str(bs)
'abcd'
  

修改

     

对于缺少bytearray的2.6之前的Python版本,您可以   请改用以下其中一项:

     
      
  • cast(buff, c_char_p).value
  •   
  • buffer(buff)[:]
  •   

如果要共享同一缓冲区,可以创建c_char数组:

>>> buff2 = (c_char * len(buff)).from_buffer(buff)
>>> buff2.value # string copy
'abcd'
>>> buff2[:] = 'efgh'
>>> buff[:]  # modified original
[101, 102, 103, 104]
  

修改

     

2.6中添加了from_buffer类方法。在以前的版本中你   可以使用cast

     
      
  • buff2 = cast(buff, POINTER(c_char * len(buff)))[0]
  •   

您是否有理由不使用c_char数组开头?我理解你是否需要将它作为数值数组和字符串使用。

附录:

第二种方法更像是“强制转换”,因为它不会复制缓冲区。第一种方法是复制两次,一次复制bytearray,再次复制strbytes是2.x中str的别名。但是bytearray有字符串方法,可能就是你所需要的;它基本上是3.x bytes的可变版本。

c_char是C char类型。乘以数组,它是一个可变的字节缓冲区,就像当前的c_ubyte数组一样。但是,它可能比c_ubyte更方便,因为它具有返回Python字节字符串的valueraw描述符。它还索引和迭代为单字符字节字符串而不是整数。

如果函数将修改它,那么你不应该做的是从Python字符串创建一个c_char_p - 一个指向字符数据的指针。 Python字符串对象是不可变的;如果修改缓冲区,你可能会得到奇怪的错误。我最近answered a question就这个话题发了言。