使用ctypes调用C结构体相关代码报AttributeError如何解决
问题解决方法
错误根源
报错是两个层面的问题共同导致的:
- C语言代码没有编写可供外部调用的导出函数,仅定义了结构体和仅适合直接运行的main函数,无法被ctypes调用
- Python代码对ctypes结构体的属性定义、动态库函数调用逻辑理解错误,你定义的结构体子类
s的字段仅包含a、b,自然不存在add1属性,调用c.add1必然触发属性报错
第一步:修改C语言代码并重新编译动态库
你需要单独写一个接收结构体参数、执行加法逻辑的导出函数,修改后的C代码如下:
#include<stdio.h> // 结构体定义保持不变 struct add1{ int a; int b; }; // 新增可供外部调用的加法函数,参数为结构体(传值) int calc_add(struct add1 s) { return s.a + s.b; } // main函数可以保留用于单独测试,不影响动态库调用 int main(){ int c; struct add1 s; printf("Enter 2 no :\n"); scanf("%d%d",&s.a,&s.b); c = s.a + s.b; printf("C is : %d",c); return c; }
使用以下命令编译生成动态库:gcc -fPIC -shared 你的C文件名.c -o add12add1.so
第二步:修改Python调用代码
你需要先导入ctypes依赖模块,删除不存在的属性调用语句,正确声明动态库函数的参数类型后再调用,修改后的代码如下:
from ctypes import CDLL, Structure, c_int # 加载动态库 obj = CDLL("./add12add1.so") print("动态库加载成功:", obj) # 定义对应C语言struct add1的Python结构体类 class Add1(Structure): _fields_ = [("a", c_int), ("b", c_int)] # 声明calc_add函数的参数类型和返回值类型 obj.calc_add.argtypes = [Add1] obj.calc_add.restype = c_int # 初始化结构体实例 s_instance = Add1(8, 9) print("结构体字段a的值:", s_instance.a) print("结构体字段b的值:", s_instance.b) # 直接在Python侧计算求和结果 print("Python侧计算求和结果:", s_instance.a + s_instance.b) # 调用C侧函数计算求和结果 c_res = obj.calc_add(s_instance) print("C侧函数返回求和结果:", c_res)
运行验证
执行修改后的Python代码,即可正常输出结果,不会再出现属性报错。
内容的提问来源于stack exchange,提问作者shaila
相关产品推荐
相关产品推荐

