使用ctypes和IronPython从字节创建结构
我有一段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
,这次它期待一个数组,但得到了字节。
你知道我哪里出错了吗?
3 个回答
0
虽然这是一篇旧帖子,但我成功地在使用Python 2.7库的情况下,让这个在IP版本2.7.5上运行起来。
import sys
sys.path.append(r"C:\Program Files (x86)\IronPython 2.7\Lib")
import ctypes
import array
class BarHeader(ctypes.Structure):
_fields_ = [("version", ctypes.c_uint)]
header = BarHeader.from_buffer_copy(array.array('c', ['\x01', '\x00', '\x00', '\x00']))
print header.version #prints 1 on little endian
1
你可以使用struct模块来处理打包的二进制数据,而不是使用ctypes。
这个模块使用一种格式字符串,里面的字符用来定义要打包或解包的数据类型。
你可以在这里找到相关文档。要读取一个包含四个字符的数组,接着是一个无符号整数,格式字符串是'4sI'。
's'表示字符数组,而4则指定了长度。'I'表示无符号整数。
示例代码:
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)
3
我在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