ctypes 的问题

2014-12-25 14:03:08 +08:00
 ryanking8215
有一个2进制网络协议,用struct模块,通过pack(),unpack()和bytes交互。
但是想和c一样,定义一个struct,不通过struct模块,行不行呢?
比如:
class T(ctypes.Structure):
_fields_=[('x',ctypes.c_uint)]

等同于c的:
struct T {
unsigned int x;
};

t = T()
如何让t直接得到bytes的数据,和转成bytes呢?

使用 f = open("kk",'wb'); f.write(t); f.close()
能把t的二进制数据直接写入文件,但是sock.write()就不行,说不是byte-ish类型。
不知其中原委,愿闻其详
2492 次点击
所在节点    Python
5 条回复
timonwong
2014-12-25 15:04:32 +08:00
因为 ctypes.Structure 类型是可以转换为 "buffer" 类型的

然后 file 类型支持写入 "buffer" 类型,因此可行。
fileobject.write(str or buffer)

bytes(buffer(t))
ryanking8215
2014-12-25 15:33:19 +08:00
@timonwong 忘了说了,我用的是python3.4,没有buffer类型。发现用bytes(t)可以直接得到二进制数据。bytes->t有什么办法吗?我现在用struct模块转,但我觉得应该有更简单的办法。
ryanking8215
2014-12-25 15:59:07 +08:00
可以这样:
b=b'1111'
PT = ctypes.POINTER(T)
pt = ctypes.cast(b,PT)
print(pt.contents)

通过ctypes.cast,将bytes对象指向的内存变为T *类型的,然后按照T类型取出内存中的数据。
fghzpqm
2014-12-26 15:10:07 +08:00
@ryanking8215 感觉你在找 Construct 这样的东西。http://construct.readthedocs.org/en/latest/
ryanking8215
2014-12-29 08:51:32 +08:00
@fghzpqm 是这么个东东,不过我用自己的方法也可以转了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/156584

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX