Python 在64位系统上读取32位压缩二进制数据
我试图编写一个PythonC扩展,它读取压缩的二进制数据(存储为structs of structs),然后将其解析为Python对象。在32位机器上(二进制文件总是在32位体系结构上编写),但在64位机器上,一切正常。有没有“首选”的方法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
要发布的代码可能很多,但举个例子:
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位整数 在处理跨平台问题时,需要注意的两个主要事项是:
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标准尺寸/校准
-
- 大端标准尺寸/对齐