Python 在64位系统上读取32位压缩二进制数据

Python 在64位系统上读取32位压缩二进制数据,python,c,64-bit,Python,C,64 Bit,我试图编写一个PythonC扩展,它读取压缩的二进制数据(存储为structs of structs),然后将其解析为Python对象。在32位机器上(二进制文件总是在32位体系结构上编写),但在64位机器上,一切正常。有没有“首选”的方法 要发布的代码可能很多,但举个例子: struct { WORD version; BOOL upgrade; time_t time1; time_t time2; } apparms; F

我试图编写一个PythonC扩展,它读取压缩的二进制数据(存储为structs of structs),然后将其解析为Python对象。在32位机器上(二进制文件总是在32位体系结构上编写),但在64位机器上,一切正常。有没有“首选”的方法


要发布的代码可能很多,但举个例子:

struct
{
    WORD    version;
    BOOL    upgrade;
    time_t  time1;
            time_t  time2;
} apparms;

File *fp;
fp = fopen(filePath, "r+b");
fread(&apparms, sizeof(apparms), 1, fp);
return Py_BuildValue("{s:i,s:l,s:l}",
  "sysVersion",apparms.version,
  "powerFailTime", apparms.time1,
  "normKitExpDate", apparms.time2
 );
现在在32位系统上,这非常有效,但在64位系统上,我的时间大小不同(32位与64位长)


妈的,你们真快

Patrick,我最初开始使用struct包,但发现它只是为了满足我的需要而放慢了速度。另外,我正在寻找编写Python扩展的借口

我知道这是一个愚蠢的问题,但我需要注意哪些类型


谢谢。

读取二进制数据的代码是什么?确保您将数据复制到适当大小的类型,如“代码> INT32×T < /代码>,而不只是<代码> int <代码> .< /p> 为什么不使用包?

,“结构”模块应该能够做到这一点,尽管数据中间的结构对齐始终是个问题。然而,要做到正确并不难:找出(一次)结构中的结构与哪个边界对齐,然后(手动地,使用“x”说明符)填充到该边界。通过将struct.calcsize()与实际数据进行比较,可以双重检查填充。这当然比为它编写C扩展容易


为了继续像那样使用Py_BuildValue(),您有两个选项。您可以在编译时确定时间的大小(根据基本类型,例如“int”或“long”或“ansize”),然后使用正确的格式字符Py_BuildValue--“i”表示int,“l”表示long,“n”表示ssize\t。或者,您可以手动使用PyInt_fromsize_t(),在这种情况下,编译器会为您执行向上转换,然后使用“O”格式字符将结果传递给Py_BuildValue。

明确指定您的数据类型(例如整数)为32位。否则,如果在读取两个整数时,两个整数相邻,则它们将被读取为一个64位整数

在处理跨平台问题时,需要注意的两个主要事项是:

  • 咬。如果压缩数据是用32位整数写入的,那么在读写时,所有代码都必须显式指定32位整数
  • 字节顺序。如果将代码从Intel芯片移动到PPC或SPARC,则字节顺序将错误。您必须导入数据,然后对其进行字节翻转,使其与当前体系结构匹配。否则,12(
    0x0000000C
    )将被读取为201326592(
    0x0000000

  • 希望这会有所帮助。

    您需要确保为结构使用独立于体系结构的成员。例如,一个int在一个架构上可以是32位,在另一个架构上可以是64位。正如其他人所建议的,使用
    int32\t
    样式类型。如果结构包含未对齐的成员,则可能还需要处理编译器添加的填充

    跨架构数据的另一个常见问题是端性。Intel i386体系结构是little endian,但如果您在完全不同的机器(例如Alpha或Sparc)上阅读,您也必须担心这一点

    Python结构模块使用作为格式字符串的一部分传递的前缀处理这两种情况

    • @-使用本机大小、端点和对齐方式。i=sizeof(int),l=sizeof(long)
    • =-使用本机endianness,但使用标准大小和对齐方式(i=32位,l=64位)
    • <-Little endian标准尺寸/校准
      • 大端标准尺寸/对齐
    一般来说,如果数据从您的计算机中传递出去,您应该将尾数和大小/填充格式固定到特定的格式,即使用“”作为格式。如果您想在C扩展中处理这个问题,您可能需要添加一些代码来处理它