【问题标题】:Python: Reading binary file into a structure and then unpackingPython:将二进制文件读入结构然后解包
【发布时间】:2015-03-22 05:53:54
【问题描述】:

我正在将 c++ 代码转换为 python。 C++ 代码读取二进制文件,然后将其转换为不同的字节序。我在 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 是一个结构。我在 python 中使用 ctypes 创建相同的结构并使用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

谢谢。

【问题讨论】:

  • 您使用的是 Python 3 还是 Python 2?你熟悉struct 模块吗?
  • @PM2Ring 我正在使用 Python 3 并且了解 struct 模块。但我不确定如何使用它。一点方向会有很大帮助。 t
  • @PM2Ring 我正在使用 Python3 并且知道 struct 但不幸的是我无法使用它。一点方向会有很大帮助。谢谢。
  • 如果您发布当前的 Python 代码会有所帮助,即使这主要是 ctypes 结构定义。 (我可能无法提供太多帮助,因为我不懂 C++,虽然我懂 C)。
  • @PM2Ring 添加了代码。让我知道您是否可以提供帮助。谢谢。

标签: python c++ endianness


【解决方案1】:

您复制的大部分代码都是一种非常复杂的字节交换int16_t 值的方式。 struct 模块可以轻松为您处理,您无需担心。

真正的问题是使用实际布局读取实际的TLEDUMPHDR。 假设您有一个具有以下布局的结构:

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

您正在从小端读取它并将其写入大端。 format'ihh';大端的标志是&gt;,小端的标志是&lt;;因此我们得到:

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)

【讨论】:

  • 如果上面的结构是嵌套结构或者里面有联合成员怎么办?
  • 这很有帮助,但我仍然无法解析结构结构或联合结构。 :(
猜你喜欢
  • 1970-01-01
  • 2015-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多