gpt4 book ai didi

python - ctypes:结构体,size_t 字段

转载 作者:太空宇宙 更新时间:2023-11-03 13:57:18 27 4
gpt4 key购买 nike

我正在尝试通过 ctypeslibnfc 实现 python-to-c 绑定(bind)。我有一个结构,这是一个错误的变体:

class nfc_iso14443a_info(Structure):
_fields_ = [
('abtAtqa', c_uint8 * 2),
('btSak', c_uint8),
('szUidLen', c_uint8 * 8),
('abtUid', c_uint8 * 10),
...

在调试 session 期间的某个时刻,它看起来像这样: enter image description here

这里的问题是我希望 szUidLen 是等于 7 的 64 位无符号整数。更准确地说,它必须与 nfc 中的 size_t szUidLen; 匹配-types.h。所以我尝试了一个明显的变体并将 c_uint8 * 8 更改为 c_size_t 但它不起作用:

class nfc_iso14443a_info(Structure):
_fields_ = [
('abtAtqa', c_uint8 * 2),
('btSak', c_uint8),
('szUidLen', c_size_t),
('abtUid', c_uint8 * 10),
...

enter image description here

我在这里缺少什么?

最佳答案

这里的问题是您尝试映射的 C 结构体已打包,如 Structure/union alignment and byte order 中(简洁地)解释的那样。文档部分:

By default, Structure and Union fields are aligned in the same way the C compiler does it. It is possible to override this behavior be specifying a _pack_ class attribute in the subclass definition. This must be set to a positive integer and specifies the maximum alignment for the fields. This is what #pragma pack(n) also does in MSVC.

只有当您已经了解 C 语言中的打包和对齐时,这才有意义,但其实并没有那么复杂。

默认情况下,C 结构元素会对齐以从良好的边界开始。例如,8 位 int 后面的 32 位 int 不是从字节 1-4 运行,而是从字节 4-7 运行(字节 1-3 是未使用的填充)。因此,ctypes 遵循相同的规则。

这意味着,虽然 szUidLen 在定义为 8 位整数数组时从字节 3-10 运行,但它会与字节 8-15(或 4-11,具体取决于字节)对齐。当它被定义为 64 位 int 时。您可以通过打印 nfc_iso14443a_info.szUidLen.offset 来查看这一点。

因此,第一个获取字节 7, 0, 0, 0, 0, 0, 0, 0,这是 7 的小端 int64,而第二个获取字节 0, 0, 0, a, b, c, d, e,其中 abcde 是下一个字段的前 5 个字节,对于某些巨大的数字来说是小端 int64(除非下一个字段恰好是 0)。

当然,您不想只是猜测这就是问题所在。如果您的 Structure 基于 C header 中的 struct,则仅当 header 或编译标志指定一些非默认打包(例如 >#pragma pack(1) 由 MSVC 使用。如果您的 Structure 基于 RFC 数据包描述之类的内容,则对齐甚至不根据 C 规则,而是在您正在阅读的文档中的某处定义(尽管协议(protocol) RFC 几乎总是使用 1-字节对齐)。

无论如何,文档并没有很好地解释问题,但他们解释了解决方案:

class nfc_iso14443a_info(Structure):
_pack_ = 1
_fields_ = [
('abtAtqa', c_uint8 * 2),
('btSak', c_uint8),
('szUidLen', c_size_t),
('abtUid', c_uint8 * 10),
...

现在 szUidLen 从字节 3-10 运行,但它被解释为 64 位 int,而不是 8 位 int 数组。

关于python - ctypes:结构体,size_t 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49502707/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com