我打算将这样的结构序列化为"压缩"二进制:
#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;
};
这里效果很好,班级的大小&#34; Foo&#34;是9,这正是我想要的。
但是当我尝试用Python 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.我想&#34; 包&#34;财产根本不起作用。消息m的二进制表示是&#34; ff000000ffffffffffffffff&#34;。
这是一个令人困惑的问题。请帮帮我。
感谢。
答案 0 :(得分:0)
如果您希望RawMessage
的sizeof为9,则需要将c_uint8
用于位字段,将c_ulonglong
用于无符号64位字段(您使用{{1}这只是4字节/ 32位)。
python 3代码,但这个想法应该转换为python 2.7:
c_ulong
输出:
#!/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))