Python ctypes与io.readinto配合不好

1 投票
1 回答
566 浏览
提问于 2025-04-18 09:33

当我用ctypes读取二进制数据时,结果不太对。

这是二进制数据

03 00 00 00 49 7B 00 00 00 00 00 00

这是Python代码

from ctypes import *

class DataStructure(Structure):
    _fields_ = [
        ("long1", c_ulong),
        #("long2", c_ulong),
        ("longlong", c_ulonglong)
    ]

binaryfile = "./ULongLong"
f = open(binaryfile, "rb")

mystruct = DataStructure()
f.readinto(mystruct)

if __name__ == "__main__":
    print mystruct.long1
    #print mystruct.long2
    print mystruct.longlong

这是结果

3
0

但是当我改用下面的二进制数据,并且取消注释那段Python代码时,结果就正常了。

03 00 00 00 03 00 00 00 49 7B 00 00 00 00 00 00

这是结果

3
3
31561

这看起来像是个bug。有没有人能帮我解决这个问题?任何建议都非常感谢。

环境: Windows 7 x64 Python 2.7 x32 ctypes 1.1.0

1 个回答

1

根据我的理解,你在处理 结构体打包 时遇到了问题。看起来你的代码读取到了“03 00 00 00 49 7B 00 00”(字长 - 64位),但只使用了前4个字节“03 00 00 00”。

更新:根据 eryksun 的说法,上面的分析是正确的。只需要在 DataStructure 的定义中设置 _pack_ = 1

一些关于 C 代码的实验:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

struct data_structure {
    uint32_t long1;
    uint64_t longlong;
};

int main(int argc, char const *argv[])
{
    FILE *fd, *other_fd;
    struct data_structure my_struct;

    my_struct.long1 = 3;
    my_struct.longlong = 31561;

    fd = fopen("ULongLong", "wb");
    if (!fd)
    {
        printf("Unable to open file!");
        return 1;
    }

    fwrite(&my_struct, sizeof(struct data_structure), 1, fd);
    fclose(fd);
    exit(0);
}

编译并运行后,检查了 ULongLong 文件:

$ hexdump ULongLong
00000000 0300 0000 0000 0000  497b 0000 0000 0000
00000010

有时候你可能会在第5到第8个字节中看到一些杂乱的数据:

$ hexdump ULongLong
00000000 0300 0000 ff7f 0000  497b 0000 0000 0000
00000010

$ hexdump ULongLong
0000000 0003 0000 7fff 0000 7b49 0000 0000 0000
0000010

这个二进制文件正确吗?

撰写回答