2013-07-09 3 views
0

로트 구조체가 정의 된 C 헤더 파일과 raw 16 진수 문자열을 사용하여 문자열을 해당 C 구조체로 파싱하고 싶습니다.바이트 구조체를 C 구조체로 파싱

이 작업을 수행하기 위해 struct.unpack()을 살펴 보았지만 형식 문자열을 자동으로 파생시킬 수있는 방법을 찾지 못했습니다.이 헤더 파일은 종종 업데이트되기 때문에 바람직합니다.

올바른 방법으로 struct.unpack() 형식 문자열을 생성하는 방법을 찾고 있습니까? 아니면 16 진수 문자열을 C 구조로 파싱하는 쉬운 방법이 있습니까?

import struct 

''' 
Example structure: 

typedef struct { 
    struct { 
    uint8_t a_flag:1; 
    uint8_t b_flag:1; 
    uint8_t c_flag:1; 
    uint8_t d_flag:1; 
    uint8_t unused:3; 
    uint8_t e_flag:1; 
    } PACKED flag_byte_0; 

    struct { 
    uint8_t unused:6; 
    uint8_t f_flag:1; 
    uint8_t g_flag:1; 
    } PACKED flag_byte_1; 

struct { 
    uint8_t unused:5; 
    uint8_t h_flag:1; 
    uint8_t i_flag:1; 
    uint8_t j_flag:1; 
} PACKED flag_byte_2; 

struct { 
    uint8_t unused:2; 
    uint8_t k_flag; 
    uint8_t l_flag:1; 
    uint8_t unused_2:4; 
} PACKED flag_byte_3; 

    uint16_t field_a; 
    uint16_t field_b; 
    uint32_t field_c:24; 
    uint32_t field_d:8; 
} PACKED struct_example; 
''' 

if __name__ == '__main__': 
    hex_string = '\x10\x08\x00\x00\x3d\x00\x08\xd7\x90\x00\x00\x0a' 
    format_string = 'BBBBHHI' 
    struct.unpack(format_string, hex_string) 
    # returns (16, 8, 0, 0, 61, 55048, 167772304) 
    # really want: 
    # a_flag:1 
    # g_flag:1 
    # ... 
    # field_a: 0x3d00 
    # etc... 
+0

당신은 당신의 게시물에 몇 가지 샘플을 포함 할 수 있습니다? 지금까지 시도한 내용을 추가하여 적어도 시도한 것을 시연하십시오. –

+0

파이썬에서 결과 구조를 처리하거나 C 함수로 전달하려고합니까? 후자의 경우에는 포장을 풀 필요가 없습니다. –

+0

@ nikolay-polivanov 파싱 된 결과는 파이썬에서 처리 될 것입니다. 주요 목표는 결과를 사람이 읽을 수있는 형식으로 표시하는 것입니다. –

답변

0

cffi 사용 :

from cffi import FFI 

ffi = FFI() 
ffi.cdef(''' 
typedef struct { 
    struct { 
    uint8_t a_flag:1; 
    uint8_t b_flag:1; 
    uint8_t c_flag:1; 
    uint8_t d_flag:1; 
    uint8_t unused:3; 
    uint8_t e_flag:1; 
    } flag_byte_0; 

    struct { 
    uint8_t unused:6; 
    uint8_t f_flag:1; 
    uint8_t g_flag:1; 
    } flag_byte_1; 

    struct { 
    uint8_t unused:5; 
    uint8_t h_flag:1; 
    uint8_t i_flag:1; 
    uint8_t j_flag:1; 
    } flag_byte_2; 

    struct { 
    uint8_t unused:2; 
    uint8_t k_flag:1; 
    uint8_t l_flag:1; 
    uint8_t unused_2:4; 
    } flag_byte_3; 

    uint16_t field_a; 
    uint16_t field_b; 
    uint32_t field_c:24; 
    uint32_t field_d:8; 
} struct_example; 
''') 


data = '\x10\x08\x00\x00\x3d\x00\x08\xd7\x90\x00\x00\x0a' 
buf = ffi.new('char[]', data) 
st = ffi.cast('struct_example*', buf) 

print st.flag_byte_0.a_flag 
print st.flag_byte_1.g_flag 
print st.flag_byte_2.h_flag 
print st.flag_byte_2.i_flag 
print st.flag_byte_2.j_flag 
print st.flag_byte_3.k_flag 
print st.flag_byte_3.l_flag 
print st.field_a 
print st.field_b 
print st.field_c 
print st.field_d 
관련 문제