2015-03-22 2 views
1

Я конвертирую код C++ в python. Код C++ считывает двоичный файл, а затем преобразует его в другую. Я сталкиваюсь с проблемой, выполняющей то же самое в python. Может ли кто-нибудь помочь мне на этом же?Python: чтение двоичного файла в структуру, а затем распаковка

Здесь C++ код:

if(bByteSwap) // make big-endian 
    { 
    pHdr = (UDUMPHDR *)buf; 
    iAPID = pHdr->sHdr.ccsdsHdr.sW1.uAPID; 
    iType = pHdr->sHdr.ccsdsHdr.sW7.uFmtID; 
    iSeqCnt = pHdr->sHdr.ccsdsHdr.uiPktSeq; 


    for(BYTE *pB=buf; pB<buf+nSz; pB+=2) ByteSwap(pB, 2); 
} 
else // already big-endian 
{ 
    ::CopyMemory(buf1, buf, nSz1); 

    for(BYTE *pB=buf1; pB<buf1+nSz1; pB+=2) ByteSwap(pB, 2); 

    pHdr1 = (UDUMPHDR *)buf1; 

    iAPID = pHdr1->sHdr.ccsdsHdr.sW1.uAPID; 
    iType = pHdr1->sHdr.ccsdsHdr.sW7.uFmtID; 
    iSeqCnt = pHdr1->sHdr.ccsdsHdr.uiPktSeq; 
} 

Здесь UDUMPHDR является структурой. Я использую ctypes в python для создания такой же структуры и используя функцию fileHandle.readinto(s) для чтения структуры из двоичного файла. Может кто-нибудь помочь мне в том, что это лучший способ сделать это?

В настоящее время Язык Python Код:

class UDUMPHDR(Union): 
_fields_ = [("sHdr", TLEDUMPHDR), 
      ("wHdr", WORD * int(sys.getsizeof(TLEDUMPHDR)/2)), 
      ("bHdr", BYTE * sys.getsizeof(TLEDUMPHDR))] 


hFile = open(myFile, 'rb') 
s = UDUMPHDR() 

print("Bytes read:", hFile.readinto(s)) 

#Make it Big Endian 
if(bByteSwap): 
    print("PktCnt:" + str(s.sHdr.pktHdr.uiPktCnt)) 
    iAPID = s.sHdr.ccsdsHdr.sW1.uAPID 
    iType = s.sHdr.ccsdsHdr.sW7.uFmtID 
    iSeqCnt = s.sHdr.ccsdsHdr.uiPktSeq 

else: 

    buf1 = copy.deepcopy(s) 
    iAPID = buf1.sHdr.ccsdsHdr.sW1.uAPID 
    iType = buf1.sHdr.ccsdsHdr.sW7.uFmtID 
    iSeqCnt = buf1.sHdr.ccsdsHdr.uiPktSeq 

Спасибо.

+0

Вы используете Python 3 или Python 2? Вы знакомы с модулем [struct] (https://docs.python.org/2/library/struct.html)? –

+0

@ PM2Ring Я использую Python 3 и знаю о структурном модуле. Но я не совсем уверен, как его использовать. Небольшое руководство могло бы помочь. t –

+0

@ PM2Ring Я использую Python3 и знаю о 'struct', но, к сожалению, я не могу его использовать. Небольшое руководство могло бы помочь. Благодарю. –

ответ

1

Большая часть кода, который вы скопировали, представляет собой очень сложный способ обмена байтов int16_t. Модуль struct может легко справиться с этим, так что вам не нужно беспокоиться об этом.

Настоящая проблема заключается в том, чтобы прочитать фактический TLEDUMPHDR с использованием его фактического расположения. Скажем, у вас есть структура со следующей планировкой:

typedef struct TLEDUMPHDR { 
    int32_t x; 
    int16_t y; 
    int16_t z; 
} TLEDUMPHDR; 

и вы читаете его из прямой порядок байтов и писать его обратным порядком байтов. format для этого - 'ihh'; а флаг для big-endian - >, а little-endian - <; таким образом мы получаем:

import struct 

buf = bytes([1,2,3,4,5,6,7,8]) # 8 bytes 

from_big_endian = struct.unpack('>ihh', buf) 
to_little_endian = struct.pack('<ihh', *from_big_endian) 
+0

Что делать, если вышеуказанная структура является вложенной структурой или имеет член объединения в ней? –

+0

Это полезно, но все же я не могу разрешить структуру структур или структуру объединений. :( –

Смежные вопросы