2010-05-08 27 views
0

我有以下CPython的代碼,我現在嘗試在IronPython的運行:創建自個字節的ctypes和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

任何想法,我做錯了嗎?

回答

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 
+0

但你有沒有在IronPython中試過它?再看看我的問題:) – Meh 2010-05-08 22:30:40

+0

你試過了嗎?好吧,我現在正在安裝這個,只爲你;) – evilpie 2010-05-08 22:33:39

+0

我不明白你爲什麼發佈的第一個樣本,這不適用於IronPython。這就像我的原始代碼,就像我說的,我的代碼在標準的Python中工作。 您的第二個示例工作。 – Meh 2010-05-08 22:40:28

1

您可以使用結構模塊,而不是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) 
+0

讓我猜,你沒有在IronPython中測試你的答案。我知道,因爲它不工作:) 但它可以固定工作。但是,我的實際結構有點複雜(我只爲這個問題保留2個字段),並且我想避免使用「4sIIIIII16s16sQQQQ」字符串 – Meh 2010-05-08 22:49:11

+0

,您可以對任何類型使用數字符號。該示例字符串實際上可以表示爲「4s 6I 16s 16s 4Q」...並且我忘記了文件不能用作緩衝區。該代碼在股票python中也不起作用;) – lunixbochs 2010-05-08 23:13:41

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