You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何读取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 05:46:08