如何像访问ctypes一样访问ctypes结构的属性,而不是通过给定的包装器?
这段内容有点不一致:
from ctypes import *
class S(Structure):
_fields_ = [("x", POINTER(c_int)), ("y", c_int)]
o = S()
print o.x
print o.y
返回的结果是
<__main__.LP_c_int object at 0x10d3d08c0>
0
在一种情况下,它返回的是一个 ctypes
类型,而在另一种情况下,它直接返回了值。
我有一些更通用的代码,里面总是需要传递一个 ctypes
类型的实例(这个实例是可以写的,也就是说,写入它就意味着修改上面例子中的 o
)。对于 o.x
这样是可以的,但 o.y
就不行。
我该如何获取 o.y
的 c_int
实例呢?
2 个回答
0
一开始我以为这只是对“正常”类型的 repr 方法有些不同,但经过一些测试后,我觉得这里肯定有些奇怪的地方。如果某个东西在结构里和不在结构里,确实会有很大的区别。
from ctypes import *
class S(Structure):
_fields_ = [("x", POINTER(c_int)), ("y", c_int), ("z", c_float)]
o = S()
x = POINTER(c_int)
y = c_int(1)
z = c_float(2.2)
print("In structure: x:{}, y:{}, z:{}".format(o.x, o.y, o.z))
print("Out of structure: x:{}, y:{}, z:{}".format(x, y, z))
在结构里:x:<main.LP_c_long 对象在 0x000000000A090EC8>, y:0, z:0.0
不在结构里:x:, y:c_long(1), z:c_float(2.200000047683716)
特别是,我觉得这应该算是个bug:
o.x.contents = y #OK
o.x.contents = o.y #not OK!!
追踪信息(最近的调用在最前面): 文件 "", 第 1 行, 在 TypeError: 期望是 c_long 而不是 int
2
从_ctypes
的源代码来看,似乎在简单的ctypes实例被包装时,它并不会进行这种聪明的自动转换。
所以,有一个(不太优雅的)解决办法是这样的:
from ctypes import *
def WrapClass(c):
class C(c): pass
C.__name__ = "wrapped_" + c.__name__
return C
class S(Structure):
_fields_ = [("x", POINTER(c_int)), ("y", WrapClass(c_int))]
o = S()
print o.x
print o.y
print o.y.value