Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 给定映射到C结构的字节,如何通过C结构访问这些字节';s变量名_Python_Python 3.x - Fatal编程技术网

Python 给定映射到C结构的字节,如何通过C结构访问这些字节';s变量名

Python 给定映射到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 {

(请容忍我,我认为是C语言,而不是Python语言,所以您可能会看到一些真正愚蠢的东西…)

我有许多(100多个)不同的C
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)
更进一步,如果C
struct
更复杂,并且包含数组和/或子结构,该怎么办?例如,类似这样的内容:

# 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黑客”