清除将IEEE float的字节表示形式插入Python ctypes uint32字段的方法?

时间:2017-08-24 19:36:19

标签: python ctypes

我正在使用外部提供的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个步骤?

2 个答案:

答案 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的相应字段中读/写。