如何读取ctypes返回指针的值?结构体数组转Python列表
使用ctypes处理C返回结构体中数组的问题
问题场景
能将Python列表转为float数组传递给C函数,但无法将C返回结构体中的数组转回Python列表。Python执行print(p)输出<__main__.c_float_Array_4 object at 0x000001FE9EEA79C0>,需要提取数组内的值。
原Python代码
class Point(ctypes.Structure): _fields_= [("a", ctypes.c_float * 4), ("aa", ctypes.c_int)] floats = [1.0, 2.0, 3.0, 4.0] FloatArray4 = (ctypes.c_float * 4) parameter_array = FloatArray4(*floats) test1 = clibrary.dosth test1.argtypes = [ctypes.c_float * 4, ctypes.c_int] test1.restype = ctypes.POINTER(Point) struc = test1(parameter_array, 9) p = (struc.contents.a) print(p) clibrary.free_memory(struc)
原C代码
#include <stdio.h> #include <stdlib.h> struct a{float *a; int aa; } ; struct a *dosth(float *lsit, int x){ struct a *b = malloc(200000); b -> a = lsit; b -> aa = 3; return b; } void free_memory(struct a *pointer){ free(pointer); }
核心问题
C结构体的a成员是float*(浮点指针),但Python的Point结构体错误地将其定义为固定大小的c_float *4数组,两者内存布局不匹配,导致无法正确解析数据。
解决步骤
1. 修正Python结构体定义
将a的类型改为ctypes.POINTER(ctypes.c_float),与C结构体的指针类型对应:
class Point(ctypes.Structure): _fields_= [("a", ctypes.POINTER(ctypes.c_float)), ("aa", ctypes.c_int)]
2. 提取数组值转为Python列表
已知数组长度为4,可通过索引遍历指针指向的内存,用列表推导式转换:
# 获取结构体内容 struc_content = struc.contents # 提取数组值(长度4) float_list = [struc_content.a[i] for i in range(4)] print(float_list) # 输出: [1.0, 2.0, 3.0, 4.0]
可选:修正C代码的冗余问题
malloc(200000)过于浪费,改为malloc(sizeof(struct a))即可分配足够内存- 变量名
lsit是拼写错误,建议改为input_arr
修正后的C代码:
#include <stdio.h> #include <stdlib.h> struct a{ float *a; int aa; }; struct a *dosth(float *input_arr, int x){ struct a *b = malloc(sizeof(struct a)); b->a = input_arr; b->aa = 3; return b; } void free_memory(struct a *pointer){ free(pointer); }
完整修正后的Python代码
import ctypes # 加载编译后的C库(根据实际库名调整,如testlib.dll或testlib.so) clibrary = ctypes.CDLL("./testlib.so") class Point(ctypes.Structure): _fields_= [("a", ctypes.POINTER(ctypes.c_float)), ("aa", ctypes.c_int)] floats = [1.0, 2.0, 3.0, 4.0] FloatArray4 = (ctypes.c_float * 4) parameter_array = FloatArray4(*floats) test1 = clibrary.dosth test1.argtypes = [ctypes.POINTER(ctypes.c_float), ctypes.c_int] test1.restype = ctypes.POINTER(Point) struc = test1(parameter_array, 9) # 提取数组值 float_list = [struc.contents.a[i] for i in range(4)] print(float_list) clibrary.free_memory(struc)
内容的提问来源于stack exchange,提问作者Sebastian
相关产品推荐
相关产品推荐

