将ctype字节数组转换为字节 [英] Convert ctype byte array to bytes
问题描述
我有一个这样定义的ctypes数组:
I have a ctypes array that I defined like this:
buff= (c_ubyte*buff_size)()
用数据填充缓冲区后,我需要以字节格式存储此数据。现在,我正在执行以下操作:
After filling the buffer up with data, I need to have this data in bytes format. Right now I'm doing it as follows:
buff= [n for n in buff]
buff = ''.join(map(chr, buff))
此问题是它将其转换为一个4字节(或任意数量的字节)int,然后再将其转换回单字节字符串,这会浪费大量CPU。
The problem with this is that it converts it to a 4-byte (or whatever number of bytes) int before converting it back into a single byte string, which wastes a lot of CPU.
如何转换ctypes直接缓冲成字节?我并不是要保存自己的副本,因为我无法保留原始缓冲区,因此无论如何我还是必须进行副本。 python是否具有此类功能的转换功能?
How can I convert the ctypes buffer into bytes directly? I'm not trying to save myself a copy because I do have to do a copy anyway since I cannot keep the original buffer. Does python have a cast feature for such things?
谢谢。
推荐答案
如果您确实想要复制,可以使用 bytearray
:
If you did want a copy, you could use bytearray
:
>>> buff = (c_ubyte * 4)(*[97,98,99,100])
>>> bs = bytearray(buff)
>>> bs
bytearray(b'abcd')
>>> str(bs)
'abcd'
编辑:
对于2.6之前的缺少 bytearray
的Python版本,您可以
而是使用以下之一:
For Python versions prior to 2.6 that lack bytearray
, you can
use one of the following instead:
-
cast(buff,c_char_p).value
-
buffer(buff)[:]
cast(buff, c_char_p).value
buffer(buff)[:]
如果要共享相同的缓冲区,则可以创建 c_char
数组:
If you want to share the same buffer, you can create a c_char
array:
>>> buff2 = (c_char * len(buff)).from_buffer(buff)
>>> buff2.value # string copy
'abcd'
>>> buff2[:] = 'efgh'
>>> buff[:] # modified original
[101, 102, 103, 104]
编辑:
from_buffer
类方法已添加2.6。在以前的版本中,
可以使用 cast
:
The from_buffer
class method was added in 2.6. In prior versions you
can use cast
:
-
buff2 = cast(buff,POINTER(c_char * len(buff)))[0]
buff2 = cast(buff, POINTER(c_char * len(buff)))[0]
您是否没有使用 c_char
数组作为理由吗?我了解您是否需要同时使用它作为数字数组和字符串。
Is there a reason you aren't using a c_char
array to begin with? I understand if you need to work with it as both a numeric array and as a string.
附录:
第二种方法更像 cast,因为它不会复制缓冲区。第一种方法是将其复制两次,一次复制为 bytearray
,再次复制为 str
( bytes
是2.x中 str
的别名。但是 bytearray
具有字符串方法,可能就是您所需要的;它基本上是3.x bytes
的可变版本。
The 2nd method is more 'cast' like since it doesn't copy the buffer. With the first approach it gets copied twice, once to make the bytearray
and again to make the str
(bytes
is an alias for str
in 2.x). But a bytearray
has string methods and may be all you need; it's basically a mutable version of 3.x bytes
.
c_char
是C char
类型。乘以一个数组,它是一个可变的字节缓冲区,例如您当前的 c_ubyte
数组。但是,它比 c_ubyte
更方便,因为它具有值
和 raw
描述符返回Python字节字符串。
c_char
is the C char
type. Multiplied to an array, it's a mutable buffer of bytes like your current c_ubyte
array. However, it may be more convenient than c_ubyte
since it has the value
and raw
descriptors that return Python byte strings. It also indexes and iterates as single character byte strings instead of integers.
您不应该做的就是创建一个 c_char_p $ $> c $ c>-指向字符数据的指针-如果函数会修改它,则来自Python字符串。 Python字符串对象是不可变的。如果您修改它们的缓冲区,则会得到奇怪的错误。我最近回答了有关该主题的问题。
What you're not supposed to do is create a c_char_p
-- a pointer to character data -- from a Python string if the function will modify the it. Python strings objects are immutable; you can get weird bugs if you modify their buffer. I recently answered a question on that topic.
这篇关于将ctype字节数组转换为字节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!