ctypes 结构上的 getattr returns 一个句柄而不是一个值

getattr on a ctypes structure returns a handle and not a value

在获取我的 ctypes 结构的 c_int 属性时,下面的代码片段似乎是 return 句柄而不是值。

如何将方法 get_val 更改为 return o_num 或 o_str 的值?

import ctypes

class my_struct(ctypes.Structure):
    _fields_=[('o_num',ctypes.c_int),('o_str',ctypes.c_wchar_p),('o_bool',ctypes.c_int),('o_err',ctypes.c_int)]

class my_substruct(ctypes.Structure):
    _fields_=[('rows',ctypes.c_int),('columns',ctypes.c_int),('next',ctypes.POINTER(my_struct))]

my_struct._fields_.append(('array',my_substruct))


class oper(ctypes.Union):
    _fields_=[('val',my_struct),('type',ctypes.c_wchar_p)]
    _mapping_={'num':'o_num','string':'o_str'}

    def get_val(self):
        return getattr(self.val,self._mapping_[self.type])

aa=my_struct(o_str='hello')
a=oper(aa,'string')
print(a.get_val())

bb=my_struct(o_num=33)
b=oper(bb,'num')
print(b.get_val())
print(bb.o_num)

由于某些原因我不明白returns

你好
263314768 ===> 这看起来像一个句柄,但为什么呢???
33

除了 Mark 的回答之外,我还测试了以下更改:

class oper(ctypes.Union):
    _fields_=[('val',my_struct),('type',ctypes.c_int)]
    _mapping_={0:'o_num',1:'o_str'}

但这为我提供了一个同样奇怪的结果:

你好
0 ===> 这同样很奇怪
33

oper声明为一个Union,所以valtype占用相同的内存。当您创建 b=oper(bb,'num') 时,两者都被写入相同的内存位置。只有一个是正确的。您在 o_num 中看到的可能是指向 'num' 字符串的 c_wchar_p

感谢 Mark 的回答,我意识到我的问题是因为 Union [相对于 Structure] 使用了该 Union 中最大类型大小的单个内存 space。另一方面,结构为结构中的每种类型分配专用内存 space。因此,将我的 Union 更改为 Structure 确实可以解决问题并防止发生这种自动转换。