2016-06-25 2 views
0

I의 의도는이 같은 구조체를 직렬화하는 "압축"진 : 그것은이다, 9이며, 여기에 잘 클래스 '푸'의 크기 작동파이썬 CTYPE _pack_ g 대 ++의 #pragma 팩

#include <cstdio> 
#include <iostream> 

using namespace std; 

#define print(x) cout << x << endl 

#pragma pack(1) 

class Foo { 
    uint32_t a: 1; 
    uint32_t b: 2; 
    uint32_t c: 5; 
    uint64_t d; 
}; 

int main() { 
    print(sizeof(char)); 
    print(sizeof(Foo)); 
    return 0; 
}; 

정확히 내가 원하는 것.

그러나 파이썬 ctypes lib로 다시 구현하려고하면 모든 것이 잘못됩니다.

import ctypes 
from io import BytesIO 
from ctypes import * 
from binascii import hexlify 

class RawMessage(ctypes.Structure): 
    _pack_ = 1 
    _fields_ = [ 
     ('a', ctypes.c_uint, 1), 
     ('b', ctypes.c_uint, 2), 
     ('c', ctypes.c_uint, 5), 
     ('d', ctypes.c_ulong), 
    ] 


def dump(o): 
    s = BytesIO() 
    s.write(o) 
    s.seek(0) 
    return hexlify(s.read()) 


if __name__ == '__main__': 
    m = RawMessage() 
    m.a = m.b = m.c = m.d = 0xFFFFFFFFFFFFFFFF 
    print ctypes.sizeof(m) 
    print dump(m) 

RawMessage의 크기는 내가 ""속성이 전혀 작동하지 않는 것 같아요 (12)이다. 메시지 m의 2 진 표현은 "ff000000ffffffffffffffff"입니다.

혼란스러운 문제입니다. 그걸 도와주세요.

감사합니다. 당신이 RawMessage의 sizeof의 9 싶은 경우

+0

나는 주위에 작업하는 문제를 해결하기로 "bitstruct"를 사용합니다. "ctypes"가 실제로이 문제를 해결할 수는 없거나 최소한이 문제를 총체적으로 해결할 수는없는 것 같습니다. – Wizmann

답변

0

, 당신은 부호없는 64 비트 필드의 비트 필드 c_uint8c_ulonglong를 사용해야합니다 (만 4 바이트/32 비트입니다 c_ulong를 사용).

파이썬 3 코드,하지만 아이디어는 2.7 파이썬 transposable해야한다 :

#!/usr/bin/python3 
import ctypes 
import io 
import binascii 

class RawMessage(ctypes.Structure): 
    _pack_ = 1 
    _fields_ = [ 
     ('a', ctypes.c_uint8 , 1), 
     ('b', ctypes.c_uint8 , 2), 
     ('c', ctypes.c_uint8 , 5), 
     ('d', ctypes.c_ulonglong), 
    ] 

def dump(o): 
    s = io.BytesIO() 
    s.write(o) 
    s.seek(0) 
    return binascii.hexlify(s.read()) 

def bin_dump(byte_buff): 
    s_buff = list() 
    for abyte in byte_buff: 
     s_buff.append("{:08b}".format(abyte)) 
    return "".join(s_buff) 

if __name__ == '__main__': 
    m = RawMessage() 
    m.a = 1 # 1 
    m.b = 1 # 01 
    m.c = int('11111', 2) # 11111 
    m.d = 0x7ffffffffffffffe # 1st and last bit set to 0 

    # note : m.a, m.b and m.c should read: 
    # 11111 01 1 -> 11111011 -> 0xfb 

    print("size of RawMessage: {}".format(ctypes.sizeof(m))) 
    buf = (ctypes.c_char * ctypes.sizeof(m)).from_buffer_copy(m) 
    bytes_buff = bytes(buf) 
    print("buffer: {}".format(bytes_buff)) 

    #print(bin_dump(bytes_buff)) 

    print(dump(m)) 

출력 :

$> py -3 so_ctypes.py 
size of RawMessage: 9 
buffer: b'\xfb\xfe\xff\xff\xff\xff\xff\xff\x7f' 
b'fbfeffffffffffff7f'