我正在使用外部提供的ctypes结构,该结构将某些字段定义为通用catch-all字段。 data
字段的类型基于mode
字段的值,如下例所示:
CONTAINS_ONE_FLOAT = 1
class TestStruct(ctypes.Structure):
pass
TestStruct._fields_ = [
('mode', ctypes.c_uint32),
('data', ctypes.c_uint32 * 2)
]
每当data
设置为mode
时,我需要在CONTAINS_ONE_FLOAT
中存储单精度(32位)浮点值。 data
的第二个单词未在此模式中使用。
到目前为止,我只能使用ctypes转换来找出这种方法。似乎过于冗长,但它确实有效。
float_value = 42.42
float_value_c = ctypes.c_float(float_value)
float_value_cp = ctypes.POINTER(ctypes.c_float)(float_value_c)
int_val_p = ctypes.cast(float_value_cp, ctypes.POINTER(ctypes.c_uint32))
int_val = int_val_p.contents
x = TestStruct()
x.mode = CONTAINS_ONE_FLOAT
x.data[0] = int_val
print("Should be 1110027796: " + str(x.data[0]))
有没有更好的方法可以做到这一点,不需要5个步骤?
答案 0 :(得分:1)
您可以使用struct
:
float_bytes = struct.pack('=f', float_value)
x.data[0] = struct.unpack('=I', float_bytes)[0]
答案 1 :(得分:1)
您描述的模式通常在C中使用union
实现;你可以用ctypes做同样的事情:
CONTAINS_ONE_FLOAT = 1
class TestStructData(ctypes.Union):
_fields_ = [
('one_float', ctypes.c_float),
('two_dword', ctypes.c_uint32 * 2)
]
class TestStruct(ctypes.Structure):
_fields_ = [
('mode', ctypes.c_uint32),
('data', TestStructData)
]
要读/写浮点数(或其他任何类型),请在TestStructData
的相应字段中读/写。