将ctype字节数组转换为字节

Mat*_*att 10 ctypes python-2.7

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

buff= (c_ubyte*buff_size)()
Run Code Online (Sandbox Code Playgroud)

在用数据填充缓冲区之后,我需要以字节格式存储这些数据.现在我正在做如下:

buff= [n for n in buff]
buff = ''.join(map(chr, buff))
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢.

Ery*_*Sun 16

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

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

编辑:

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

  • 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]
Run Code Online (Sandbox Code Playgroud)

编辑:

from_buffer在2.6中加入类方法.在以前的版本中,您可以使用cast:

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

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

附录:

第二种方法更像是"强制转换",因为它不会复制缓冲区.使用第一种方法,它会被复制两次,一次制作bytearray并再次制作str(bytesstr2.x中的别名).但是有一个bytearray字符串方法,可能就是你所需要的; 它基本上是3.x的可变版本bytes.

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

c_char_p如果函数将修改它,那么你不应该做的是从Python字符串创建一个指向字符数据的指针.Python字符串对象是不可变的; 如果修改缓冲区,你可能会得到奇怪的错误.我最近回答了有关该主题的问题.