(请耐心等待,我认为是用 C 而不是 Python,所以你可能会看到一些真正愚蠢的东西......)
我有许多(100 多个)不同的 C structs
,作为 bytes
被拉入 Python(版本 3.5.1),我希望能够使用原始 C 结构的变量名。这是一个简单的例子。在 Python 中,我收到了这些 bytes
:
# In Python:
example1_bytes = b'\x08\x09\x0a\x0b'
假设这些 bytes
是由运行 C 的东西提供的,使用以下格式的 struct
:
// In C:
struct example1 {
uint8_t val1;
uint8_t val2;
uint8_t val3;
uint8_t val4; };
我如何处理 example1_bytes
以便我可以像这样访问它们:
# In Python:
result = process_example1_bytes(example1_bytes)
print(result.val1)
# Prints "8"
print(result.val2)
# Prints "9"
# Et cetera
更进一步,如果 C struct
更复杂并且包含数组和/或子结构怎么办?例如,像这样:
// In C:
struct substruct {
uint8_t ss_val1;
uint8_t ss_val2; };
struct example2 {
uint8_t val1;
uint8_t val2;
struct substruct ss[8]; };
如何处理 example2_bytes
以便我可以像这样访问它们:
# In Python:
result = process_example2_bytes(example2_bytes)
print(result.val1)
print(result.ss[3].ss_val2)
我使用 Python 的 struct
unpack
做了一些实验,它返回元组,我认为是朝着正确方向迈出的一步,但是它并没有完全让我找到我想要的可用解决方案。我不确定我是否需要沿着 namedtuple
路径走下去或采取其他方向。
最佳答案
您正在寻找 ctypes
library ,它允许您为复杂的底层 C 结构定义 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
因此,除了 Structures
和 Arrays
之外,它还支持 Union
和指针,以及为 C 程序员提供的各种好东西.
请注意,您正在使用 bytes
对象,这些对象是不可变的,并且在创建结构时需要一个副本。但是,如果您使用 bytearray
,则不需要底层缓冲区的副本!
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'
但是,使用字节数组:
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')
关于python - 给定映射到 C 结构的字节,如何通过 C 结构的变量名访问字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48552043/