2010-05-08 3 views
0

내가 지금은 IronPython에서 실행하려고 다음의 CPython 코드가 있습니다 TypeError: expected array, got str하는 ctypes와 IronPython을 가진 바이트에서 구조를 만들기

내가 대신 BarHeader.from_buffer_copy(bytes(header_raw)) 시도 : 마지막 줄이 예외가 발생

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 bytes으로 변경됩니다.

내가 뭘 잘못하고 있는지 아는 사람이 있습니까?

답변

1

파이썬 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 

그리고 당신은 압축 된 바이너리 데이터 작업을 대신하는 ctypes의 구조체 모듈을 사용할 수있는 배열 클래스

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

+0

당신은 그것을 시도 했습니까? 자, 이제 설치하고 있습니다.) – evilpie

+0

IronPython에서 작동하지 않는 첫 번째 샘플을 왜 게시했는지 이해할 수 없습니다. 그것은 마치 원래 코드와 같으며, 필자가 말했듯이, 내 코드는 표준 파이썬에서 작동합니다. 두 번째 샘플이 작동합니다. – Meh

1

를 사용하여 솔루션입니다.

팩 스/압축 해제 할 데이터 유형을 정의하는 문자가있는 형식 문자열을 사용합니다.

설명서는 here입니다. 4 문자 배열을 읽는 형식 문자열이면 부호없는 정수는 '4sI'가됩니다.

's'는 문자 배열의 문자이고 4는 길이를 지정합니다. 'I'는 부호없는 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

+0

모든 유형에 대해 숫자 표기법을 사용할 수 있습니다. 예제 문자열은 실제로 "4s 6l 16s 16s 4q"로 표현 될 수 있습니다 ... 그리고 파일을 버퍼로 사용할 수 없음을 잊었습니다. 그 코드는 주식 파이썬에서 작동하지 않았다;) – lunixbochs

0

이 이전 게시물이지만, 나는이 파이썬 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 
관련 문제