为什么 ctypes.c_int 在放入 ctypes 结构时会完全改变其行为?

Why does ctypes.c_int completely change its behaviour when put into ctypes Structure?

当我创建类型为 ctype.c_int 的变量时,它报告该类型并且不允许任何数学运算:

In [107]: x = c_int(1)
In [108]: x
Out[108]: c_int(1)
In [109]: x+=1
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
----> 1 x+=1
TypeError: unsupported operand type(s) for +=: 'c_int' and 'int'

In [110]: x+=x
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
----> 1 x+=x
TypeError: unsupported operand type(s) for +=: 'c_int' and 'c_int'

In [111]: type(x)
Out[111]: ctypes.c_int

另一方面:当我创建一个内部带有 c_int 的结构时,它被报告为 int,允许数学运算,但似乎仍然存储为 32 位 c 整数,因为它在 32 位上正确换行,并在位置 31 处使用符号位。

In [112]: class REC(ctypes.Structure): _fields_=[('x',ctypes.c_int),('y',ctypes.c_int)]
In [113]: rec = REC()

In [114]: rec.x
Out[114]: 0

In [114]: type(rec.x)
Out[114]: int                       # why not ctypes.c_int ???

In [116]: rec.x+=0x7FFFFFFF         # += works, so it is regular python int ?

In [117]: rec.x
Out[117]: 2147483647

In [118]: rec.x+=1

In [119]: rec.x
Out[119]: -2147483648               # but it honors sign bit at position 31...

In [122]: rec.x=0xFFFFFFFF

In [123]: rec.x
Out[123]: -1

In [124]: rec.x+=1

In [125]: rec.x
Out[125]: 0                         # ...and it wraps on 32 bits, so it is NOT python int!

有人可以解释这种行为吗?这背后有什么逻辑吗?

c_int必须有两个身份addressof可能被占用的C对象,Python对象x。前者是一个整数,而后者不是。 (回想一下 x=2 只会重新绑定 x 而不会更新 C 整数。)

当您将变量放入结构中时,ctypes 可以提供一个 便利 ,一个 attribute-based 在 C 和 Python表示。这有它自己的惊喜:存储一个适当大的值,然后你会看到 rec.x is not rec.x。制造的对象是真实的 Python 对象,但它们当然不遵循 Python 规则 ,因为它们不拥有任何数据。

这同样适用于裸整数的 value 属性。

奇怪的是,它 相当于结构中的裸整数,因此您不能轻易地将结构成员传递给函数来填充它。