【问题标题】:Python ctypes with io.readinto doesn't work well带有 io.readinto 的 Python ctypes 不能正常工作
【发布时间】:2014-06-12 13:20:24
【问题描述】:

当我用 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

这似乎是一个错误。有人可以帮我解决这个问题吗? 任何建议都将不胜感激。

环境: 视窗 7 x64 Python 2.7 x32 ctypes 1.1.0

【问题讨论】:

    标签: python ctypes


    【解决方案1】:

    据我了解,structure packing 有问题。看起来您的代码正在读取“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
    

    这个二进制文件正确吗?

    【讨论】:

    • 在 Windows 上,ctypes 将结构对齐到 8 个字节。检查ctypes.alignment(mystruct)。请补充一下,解决方法是在DataStructure的定义中设置_pack_ = 1
    猜你喜欢
    • 2023-01-21
    • 2022-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-22
    • 1970-01-01
    • 2017-10-15
    • 1970-01-01
    相关资源
    最近更新 更多