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

基于SWIG实现C函数generate_buffer的Python接口遇类型映射问题

解决SWIG多参数类型映射的垃圾值问题

原C代码

typedef struct My_Struct {
    int x;
    int y;
} my_struct_t;

void generate_buffer(my_struct_t info, uint8_t* buffer_out);

需求是通过SWIG实现Python调用generate_buffer,输出缓冲区大小由info.x指定,同时保证C函数能正常访问info,分配的内存可正确回收。

你当前的类型映射出现垃圾值问题,核心原因是多参数类型映射的$input对应的是Python传入的参数元组,而非单个结构体对象,直接对整个元组调用SWIG_ConvertPtr必然会得到错误数据。

修正后的SWIG类型映射

// 输入类型映射:正确解析参数元组
%typemap(in) (my_struct_t info, uint8_t* buffer_out) %{
    // 从参数元组中取出第一个元素(my_struct_t实例)
    PyObject* struct_obj = PyTuple_GetItem($input, 0);
    my_struct_t tmp;
    int res1 = SWIG_ConvertPtr(struct_obj, (void*)&tmp, SWIGTYPE_p_My_Struct, 0);
    if (!SWIG_IsOK(res1)) {
        SWIG_exception_fail(SWIG_ArgError(res1), "无法转换为my_struct_t类型");
    }

    // 按info.x分配缓冲区,增加分配失败判断
    $2 = (uint8_t*)malloc(tmp.x);
    if (!$2) {
        SWIG_exception_fail(SWIG_MemoryError, "内存分配失败");
    }
    $1 = tmp;
%}

// 输出类型映射:将缓冲区转为Python bytes对象
%typemap(argout) (my_struct_t info, uint8_t* buffer_out) (PyObject* po) %{
    po = PyBytes_FromStringAndSize((char*)$2, $1.x);
    $result = SWIG_Python_AppendOutput($result, po);
%}

// 释放参数内存:增加非空判断避免野指针
%typemap(freearg) (my_struct_t info, uint8_t* buffer_out) %{
    if ($2) {
        free($2);
        $2 = NULL;
    }
%}

接口文件注意事项

确保SWIG先完成my_struct_t的Python包装,再应用类型映射:

%module example
%{
#include "你的头文件.h"
%}

// 让SWIG生成my_struct_t的Python绑定
typedef struct My_Struct {
    int x;
    int y;
} my_struct_t;

// 应用类型映射到目标函数的参数
%apply (my_struct_t info, uint8_t* buffer_out) { (my_struct_t info, uint8_t* buffer_out) };
void generate_buffer(my_struct_t info, uint8_t* buffer_out);

关键修复点

  • 解析参数元组:多参数类型映射的$input是Python传入的参数元组,必须用PyTuple_GetItem取出对应位置的参数再转换。
  • 内存安全:增加malloc失败判断,freearg阶段增加非空检查,避免野指针和重复释放。
  • 类型映射作用范围:用%apply明确将类型映射绑定到目标函数的参数列表,确保生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 11:02:42