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

如何通过SWIG在Python中访问C语言的二级指针?

解决SWIG包装C结构体数组返回的段错误问题

问题根源分析

你当前的代码存在几个关键错误:

  • 类型宏拼写错误:WIGTYPE_p_p_t_type1应该是SWIGTYPE_p_t_type1,因为*$1是t_type1*(指向数组首元素的指针),而非二级指针
  • 输入typemap的局部变量冗余:test_func是把内部缓冲区的指针写入传入的指针地址,不需要额外声明局部t_type1 *temp
  • 未处理结构体内部的固定数组:t_type1和t_type2里的数组(如a[16]、ch[10])默认不会被SWIG正确映射为Python可访问的序列,直接访问会触发内存错误
  • 指针所有权标识不明确:需要明确告诉SWIG该内部缓冲区不需要Python管理内存

可行解决方案

以下是修正后的SWIG接口文件示例,包含完整的类型映射和数组处理逻辑:

1. 完整SWIG接口代码(test.i)

%module test_wrap

// 导入carray库处理C固定数组,让Python可以像列表一样访问
%include <carray.i>
%array_class(uint8_t, uint8Array);
%array_class(t_type2, t_type2Array);

// 定义C侧的类型和函数
typedef unsigned char uint8_t;
typedef uint8_t t_dtbt_uint8;

typedef struct
{
  uint8_t a[16];
  uint8_t b;
  uint8_t c;
  uint8_t d;
  uint8_t e;
  uint8_t f;
}t_type2;

typedef struct
{
  uint8_t a[16];
  uint8_t b;
  uint8_t c;
  uint8_t d;
  t_type2 ch[10];
  uint8_t e;
}t_type1;

// 修正输入typemap:让函数接收一个指针地址,用于存储内部缓冲区的指针
%typemap(in, numinputs=0) t_type1 **types_result (t_type1 *out_ptr) {
  $1 = &out_ptr;
}

// 修正输出typemap:将返回的t_type1*指针包装为Python对象,明确内存所有权
%typemap(argout) t_type1 **types_result {
  // 这里*$1是t_type1*,对应SWIGTYPE_p_t_type1,所有权设为0表示Python不释放内存
  $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, SWIGTYPE_p_t_type1, 0));
}

// 声明要包装的函数
t_dtbt_uint8 test_func(t_type1 **types_result);

2. Python调用示例

编译生成包装模块后,你可以这样访问数组元素:

import test_wrap

err, types_ptr = test_wrap.test_func()

# 访问t_type1数组的第一个元素
first_type1 = types_ptr[0]

# 访问first_type1的a数组(转为Python列表)
a_list = [first_type1.a[i] for i in range(16)]

# 访问ch数组的第3个元素(索引从0开始)
third_ch = first_type1.ch[2]
print(third_ch.b)

关键细节说明

  • carray.i的作用:SWIG默认不会把C固定数组映射为Python可迭代对象,%array_class会生成对应的包装类,让你可以通过索引访问数组元素
  • 内存所有权:SWIG_NewPointerObj的第三个参数设为0,表示该指针指向的内部缓冲区由C侧管理,Python不会尝试释放它,避免野指针或重复释放
  • 输入typemap修正:直接声明out_ptr变量,让$1指向它的地址,test_func会把内部缓冲区的指针写入这个变量,后续输出typemap再把它包装成Python对象

内容的提问来源于stack exchange,提问作者donpedro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 21:03:34