如何通过ctypes在C中修改Python列表并返回修改后的列表?
问题分析与解决方案
你的核心问题是没有正确保存ctypes数组对象并提取修改后的值:原代码直接传递临时的ctypes数组对象给C函数,还错误地将void类型C函数的返回值(None)赋值给变量,导致无法获取修改后的结果。
修正后的Python代码
import os import ctypes current_dir = os.getcwd() full_path = os.path.join(current_dir, "lib.so") # 用os.path.join避免路径拼接错误 _lib = ctypes.CDLL(full_path) _lib.apply_cosine.argtypes = (ctypes.POINTER(ctypes.c_double), ctypes.c_int) _lib.apply_cosine.restype = None # 明确指定返回类型为void,避免默认推断错误 def apply_cosine(array: list) -> list: '''Wrapper function to apply cosine function to each element in the list. ''' length = len(array) # 创建ctypes数组对象,并用Python列表初始化 c_array = (ctypes.c_double * length)(*array) # 调用C函数,传入数组指针(ctypes自动转换)和长度 _lib.apply_cosine(c_array, length) # 将修改后的ctypes数组转换为Python列表返回 return list(c_array) if __name__ == "__main__": test = [12., 44., 23., 32., 244., 23.] print(apply_cosine(test))
关键修正点
- 保存ctypes数组对象:创建
c_array变量存储ctypes数组,确保C函数修改的是我们能访问到的内存区域,而非临时销毁的对象。 - 正确处理返回值:C函数为
void类型,显式指定restype = None,且不将函数调用结果赋值给变量。 - 提取修改后的数据:C函数执行完成后,直接将
c_array转换为Python列表返回,此时数组内容已被修改。
编译C代码的注意事项
由于用到了math.h中的cos函数,编译时需要链接数学库,执行以下命令:
gcc -shared -fPIC -o lib.so iterator.c -lm
内容的提问来源于stack exchange,提问作者mm117
相关产品推荐
相关产品推荐

