Python 给定映射到C结构的字节,如何通过C结构访问这些字节';s变量名
(请容忍我,我认为是C语言,而不是Python语言,所以您可能会看到一些真正愚蠢的东西…) 我有许多(100多个)不同的CPython 给定映射到C结构的字节,如何通过C结构访问这些字节';s变量名,python,python-3.x,Python,Python 3.x,(请容忍我,我认为是C语言,而不是Python语言,所以您可能会看到一些真正愚蠢的东西…) 我有许多(100多个)不同的Cstruct,作为字节拉入Python(3.5.1版),我希望能够使用原始C结构的变量名访问它们。这里有一个简单的例子。在Python中,我收到了以下字节: # In Python: example1_bytes = b'\x08\x09\x0a\x0b' 假设这些字节是由运行C的某个程序使用以下格式的结构提供的: // In C: struct example1 {
struct
,作为字节拉入Python(3.5.1版),我希望能够使用原始C结构的变量名访问它们。这里有一个简单的例子。在Python中,我收到了以下字节
:
# In Python:
example1_bytes = b'\x08\x09\x0a\x0b'
假设这些字节
是由运行C的某个程序使用以下格式的结构提供的:
// In C:
struct example1 {
uint8_t val1;
uint8_t val2;
uint8_t val3;
uint8_t val4; };
我如何处理example1_字节
,以便像这样访问它们:
# In Python:
result = process_example1_bytes(example1_bytes)
print(result.val1)
# Prints "8"
print(result.val2)
# Prints "9"
# Et cetera
// In C:
struct substruct {
uint8_t ss_val1;
uint8_t ss_val2; };
struct example2 {
uint8_t val1;
uint8_t val2;
struct substruct ss[8]; };
# In Python:
result = process_example2_bytes(example2_bytes)
print(result.val1)
print(result.ss[3].ss_val2)
更进一步,如果Cstruct
更复杂,并且包含数组和/或子结构,该怎么办?例如,类似这样的内容:
# In Python:
result = process_example1_bytes(example1_bytes)
print(result.val1)
# Prints "8"
print(result.val2)
# Prints "9"
# Et cetera
// In C:
struct substruct {
uint8_t ss_val1;
uint8_t ss_val2; };
struct example2 {
uint8_t val1;
uint8_t val2;
struct substruct ss[8]; };
# In Python:
result = process_example2_bytes(example2_bytes)
print(result.val1)
print(result.ss[3].ss_val2)
如何处理example2_字节
,以便像这样访问它们:
# In Python:
result = process_example1_bytes(example1_bytes)
print(result.val1)
# Prints "8"
print(result.val2)
# Prints "9"
# Et cetera
// In C:
struct substruct {
uint8_t ss_val1;
uint8_t ss_val2; };
struct example2 {
uint8_t val1;
uint8_t val2;
struct substruct ss[8]; };
# In Python:
result = process_example2_bytes(example2_bytes)
print(result.val1)
print(result.ss[3].ss_val2)
我曾经尝试过使用Python的struct
unpack
,它返回元组,我认为这是朝着正确方向迈出的一步,但它并没有让我找到我想要的可用解决方案。我不确定我是否需要沿着namedtuple
路径走,或者走其他方向。您正在寻找,它允许您为复杂的底层C-struct定义Python包装器。对于简单类型:
import ctypes
example1_bytes = b'\x08\x09\x0a\x0b'
class Example1(ctypes.Structure):
_fields_ = (
('val1', ctypes.c_uint8),
('val2', ctypes.c_uint8),
('val3', ctypes.c_uint8),
('val4', ctypes.c_uint8)
)
ex1 = Example1.from_buffer_copy(example1_bytes)
print(ex1.val1, ex1.val2, ex1.val3, ex1.val4, sep='|')
# 8|9|10|11
更复杂的结构:
class substruct(ctypes.Structure):
_fields_ = (
('ss_val1', ctypes.c_uint8),
('ss_val2', ctypes.c_uint8),
)
class Example2(ctypes.Structure):
_fields_ = (
('val1', ctypes.c_uint8),
('val2', ctypes.c_uint8),
('ss', substruct*8), #array type!
)
注意,您可以使用乘法运算符定义大小为n
的T
类型的数组<代码>T*n
因此,除了结构
和数组
之外,它还支持联合
和指针,并且包含了C程序员的各种好处
注意,您使用的是字节
对象,这些对象是不可变的,在创建结构时需要一个副本。但是,如果使用字节数组
,则不需要底层缓冲区的副本!:
In [4]: example1_bytes
Out[4]: b'\x08\t\n\x0b'
In [5]: ex1.val2 = 99
In [6]: example1_bytes
Out[6]: b'\x08\t\n\x0b'
但是,使用bytearray:
In [16]: buffer = bytearray(example1_bytes)
In [17]: ex2 = Example1.from_buffer(buffer)
In [18]: ex2
Out[18]: <__main__.Example1 at 0x10a5b5598>
In [19]: buffer
Out[19]: bytearray(b'\x08\t\n\x0b')
In [20]: ex2.val2 = 99
In [21]: buffer
Out[21]: bytearray(b'\x08c\n\x0b')
[16]中的:buffer=bytearray(例如1个字节)
在[17]中:ex2=Example1.from_buffer(buffer)
In[18]:ex2
出[18]:
In[19]:缓冲区
Out[19]:字节数组(b'\x08\t\n\x0b')
In[20]:ex2.val2=99
In[21]:缓冲区
Out[21]:字节数组(b'\x08c\n\x0b')
相关:非常有用的答案。谢谢@安德鲁科特雷尔,不客气!希望这能使从C到Python的转换过程稍微不那么痛苦。注意,Python和C是天生的朋友,当Guido创建Python时,他的目标是“Unix/C黑客”