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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 03:36:05