Python ctypes如何为含float指针成员的结构体传递指针值
ctypes结构体float指针成员赋值正确方法
错误原因
你之前的两种写法都不符合ctypes的类型规则:
- 直接给
POINTER(c_float)类型成员赋值Python数字字面量:不存在对应隐式类型转换,会直接抛出类型不匹配错误 - 把数字字面量直接cast成指针:相当于把数字本身当成内存地址,生成的是野指针,调用C接口时会触发内存访问错误
正确赋值逻辑
C里的指针本质是内存地址,你必须先创建一个实际存在内存里的c_float类型实例,再把指向这个实例的指针赋值给结构体成员,同时要保证这个c_float实例的生命周期覆盖整个C接口调用周期,避免被Python GC回收生成悬垂指针。
场景1:传递单个float值的指针
这是当前代码需要的场景,直接用ctypes.pointer()包装一个c_float实例即可:
import ctypes # 结构体定义保持原有逻辑即可 class input_struct (ctypes.Structure): _fields_ = [ ('number1', ctypes.POINTER(ctypes.c_float)), ('number2', ctypes.c_float), #('option_enum', ctypes.POINTER(option)) ] init_func = c_instance.expose_init init_func.argtypes = [ctypes.POINTER(input_struct)] inp_str_ptr = input_struct() # 先创建持有值20.0的c_float实例,绑定到独立变量上避免被GC回收 num1_val = ctypes.c_float(20.0) # 取实例的指针赋值给结构体成员 inp_str_ptr.number1 = ctypes.pointer(num1_val) inp_str_ptr.number2 = 100 c_instance.expose_init(ctypes.byref(inp_str_ptr)) c_instance.expose_operation()
注意:不要写匿名实例赋值的写法
inp_str_ptr.number1 = ctypes.pointer(ctypes.c_float(20.0)),没有外部引用的匿名c_float实例可能在调用C接口前就被GC回收,导致指针指向无效内存。
场景2:传递float数组的指针
如果C接口中number1实际是长度为N的float数组首地址,可以直接创建ctypes数组实例赋值,数组会自动隐式转换为指向首元素的指针:
# 示例:传递长度为3、值为[20.0, 30.0, 40.0]的float数组 float_arr = (ctypes.c_float * 3)(20.0, 30.0, 40.0) inp_str_ptr.number1 = float_arr
踩坑提醒
- 不要给指针类型成员直接传Python原生数值,必须经过对应ctypes类型包装
- 所有被指针指向的ctypes实例,都要保证在C接口使用指针的全周期内有Python侧的变量引用,避免GC回收导致悬垂指针
- 后续如果开启注释中的枚举指针成员,赋值逻辑完全一致:先创建枚举类型实例,再传递实例的指针即可
内容的提问来源于stack exchange,提问作者soundarrajan v
相关产品推荐
相关产品推荐

