使用ctypes和IronPython从字节创建结构

时间:2010-05-08 21:52:51

标签: python ironpython ctypes

我有以下CPython代码,我现在尝试在IronPython中运行:

import ctypes

class BarHeader(ctypes.Structure):
    _fields_ = [
        ("id", ctypes.c_char * 4),
        ("version", ctypes.c_uint32)]

bar_file = open("data.bar", "rb")
header_raw = bar_file.read(ctypes.sizeof(BarHeader))
header = BarHeader.from_buffer_copy(header_raw)

最后一行引发了此异常:TypeError: expected array, got str

我尝试了BarHeader.from_buffer_copy(bytes(header_raw))而不是上述内容,但异常消息更改为TypeError: expected array, got bytes

知道我做错了吗?

2 个答案:

答案 0 :(得分:1)

我在Python 2.7中尝试了以下代码,它运行得很好。

import ctypes  

class BarHeader(ctypes.Structure):
   _fields_ = [("version", ctypes.c_uint)]


header = BarHeader.from_buffer_copy("\x01\x00\x00\x00")
print header.version #prints 1 on little endian

使用数组类的解决方案

import ctypes
import array

class BarHeader(ctypes.Structure):
   _fields_ = [
      ("id", ctypes.c_char * 4),
      ("version", ctypes.c_uint32)]

bar_file = open("data.bar", "rb")

bytearray = array.array('b')
bytearray.fromfile(bar_file, ctypes.sizeof(BarHeader))

header = BarHeader.from_buffer_copy(bytearray)

print header.id
print header.version

答案 1 :(得分:1)

您可以使用struct模块而不是ctypes来处理压缩二进制数据。

它使用格式字符串,其中的字符定义要打包/解包的数据类型。

找到文档here。 用于读取四个字符数组的格式字符串,然后是无符号整数,将为“4sI”。

's'是char数组的字符,而4指定长度。 '我'是unsigned int的字符。

示例代码:

import struct

header_fmt = struct.Struct("4sI")

bar_file = open("data.bar", "rb")
header_raw = bar_file.read(header_fmt.size)
id, version = header_fmt.unpack(header_raw)