【问题标题】:Why ctypes sizeof treats c_ubyte*1 and c_char*1 in the structure differently?为什么 ctypes sizeof 以不同的方式对待结构中的 c_ubyte*1 和 c_char*1?
【发布时间】:2013-01-27 11:30:37
【问题描述】:

当我用c_char 数组定义一个ctypes 结构作为字段时,我无法获得该字段的大小,但如果我切换到c_ubyte 数组,我可以。我的理解是,在以下示例中,Python 将bar2 视为指针(char*),而不是bar1。如果有人能解释其背后的逻辑,我将不胜感激。

import ctypes
class Foo(ctypes.Structure):
    _fields_ = [ ('bar1', ctypes.c_ubyte*1),
                 ('bar2', ctypes.c_char*1) ]
foo = Foo()
for f,t in foo._fields_:
    print t

print ctypes.sizeof(foo.bar1)
print ctypes.sizeof(foo.bar2)

这是输出:

<class '__main__.c_ubyte_Array_1'>
<class '__main__.c_char_Array_1'>
1
Traceback (most recent call last):
  File "test.py", line 12, in <module>
    print ctypes.sizeof(foo.bar2)
TypeError: this type has no size

【问题讨论】:

  • 我怀疑这与 C 对待 char 和 char 数组的方式与 Python 在两者都是序列的方式不同方面有关。只需使用ctypes.c_byte 而不是ctypes.c_charfoo.bar2 就会有大小。
  • @martineau 对,我使用的是ctypes.c_ubyte。尝试根据标准 char sin_zero[8] 定义 sockaddr_in 时遇到该问题

标签: python ctypes


【解决方案1】:

foo.bar1 确实是一个 1 ubyte 的 ctypes 数组,但 foo.bar2 是一个由数组中的内容组成的字符串,被视为以 null 结尾的 C 字符串。如果您制作更长的数组(例如长度为 5)会更清楚:如果它们包含例如重复的字符“A”,那么foo.bar1 将读取为

<__main__.c_ubyte_Array_5 object at 0xf7551df4>

foo.bar2 会读作

"AAAAA"

这是一个普通的 Python 字符串。这是c_char 类型的特例。确实,这很烦人,因为首先没有干净的方法将此值 "AAAAA" 写入 bar2...

【讨论】:

  • 所以你说foo.bar2 被自动转换为 Python 字符串。这就解释了。我可以改用len(foo.bar2)。一个有趣的观察是a = ctypes.c_char*5 不遵循这种行为。 class Foo(ctypes.Structure): fields = [ ('bar', ctypes.c_char*5) ] foo = Foo("12345")` 无错误地转换为字符串,而 @ 987654334@ 被视为真正的 char 数组:a = (ctypes.c_char*5)("12345") 失败并显示 TypeError: one character string expected。我想知道这是一个错误还是 ctypes 的一个特性。
  • 此时我可以为 cffi 投放广告:它是 ctypes 的更简单替代品。 cffi.readthedocs.org
猜你喜欢
  • 2021-07-23
  • 1970-01-01
  • 2011-03-07
  • 1970-01-01
  • 1970-01-01
  • 2022-10-19
  • 1970-01-01
  • 2014-06-20
  • 2018-03-05
相关资源
最近更新 更多