我尝试写一Python C扩展读包装的二进制数据(它被储存作为结构结构),然后分析这到蟒蛇的对象。一切正常,因为预计上的一个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位我time_t大小不同(32位vs64位渴望).


该死的,你们都快。

帕特里克,我最初开始使用的结构的软件包,但发现它只是方式减慢我的需要。加上我正在寻找借口,编写一Python扩展。

我知道这是个愚蠢的问题但是什么类型的我需要看的?

谢谢。

有帮助吗?

解决方案

明确指定的数据类型(例如整数)是32位。否则,如果你有两个整数下一次到每一其他当你读到他们,他们会被解读为一64位整数。

当你们面对的交叉平台的问题,两个主要的事情要注意的是:

  1. 位.如果你打包的数据写入有32位整数,然后所有的代码必须明确指定的32位整数时的阅读 写作。
  2. 字节的顺序。如果你移动你的代码从英特尔薯条,PPC或SPARC,你的字节的顺序将是错误的。你将不得不进口数据并字节翻转它,使其符合起来与目前的结构。否则12(0x0000000C)将读作201326592(0x0C000000).

希望这有所帮助。

其他提示

'struct'模块应该能够做到这一点,尽管数据中间的结构对齐始终是个问题。然而,要做到这一点并不是很难:找出(一次)结构结构对齐的边界,然后用手工填充(用'x'说明符)到那个边界。您可以通过将struct.calcsize()与实际数据进行比较来双击填充。它肯定比为它编写C扩展更容易。

为了继续使用Py_BuildValue(),你有两个选择。您可以在编译时确定time_t的大小(根据基本类型,所以'int'或'a long'或'ssize_t')然后使用正确的格式字符到Py_BuildValue - 'i'表示int, 'l'为长,'n'为ssize_t。或者您可以手动使用PyInt_FromSsize_t(),在这种情况下,编译器会为您执行向上转换,然后使用“O”格式字符将结果传递给Py_BuildValue。

你需要确保在使用的建筑独立的成员结构。例如int可能是32位上一个建筑和64位于另一个。正如其他人所建议的使用 int32_t 风格的类型来代替。如果你的结构包含了不结盟成员,可能需要处理的填充增加通过编译器。

另一个常见的问题具有交叉结构的数据字节序.英特尔i386构是little-endian,但是如果你读上一个完全不同的机器(例如一个阿尔法或Sparc),只有担心这个了。

蟒蛇的结构模块的交易与这些情况下,使用该前缀的传递作为一部分的格式串。

  • @使用的土大小、字节序和准。i=sizeof(int),l=sizeof(long)
  • =-使用本字节序,但是标准尺寸和准(i=32位,l=64位)
  • < -Little-endian标准尺寸/准
    • Big-endian标准尺寸/准

在一般情况下,如果数据传递掉你的机器,应该指甲下的字节序和尺寸/填充格式的一些具体的事情—ie。使用"<"或者">"作为你的格式。如果你要处理这在你C扩展,可能需要添加一些代码处理它。

您阅读二进制数据的代码是什么?确保将数据复制到大小合适的类型,例如int32_t,而不仅仅是int

为什么不使用 struct 软件包?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top