在 SWIG 输入类型映射中释放指针数组的正确方法? [英] Proper way to free a pointer array in SWIG input typemap?

查看:29
本文介绍了在 SWIG 输入类型映射中释放指针数组的正确方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 SWIG 包装以下函数.

Hi I'm trying to wrap the following function using SWIG.

static void readTable(int argc, t_atom *argv) { //accepts table in Lua e.g. readTable({"ab",3});

        for (int i=0; i<argc; ++i) {

            if (argv[i].a_type == A_FLOAT)
                printf("FLOAT : %g
", argv[i].a_w.w_float);
            else if (argv[i].a_type == A_SYMBOL)
                printf("SYMBOL : %s
", argv[i].a_w.w_symbol->s_name);
        }
    }

这是我创建的类型映射.

Here's the typemap I created.

%include "exception.i"
%typemap(in) (int argc, t_atom *argv)
{
    if (!lua_istable(L, 1)) {
      SWIG_exception(SWIG_RuntimeError, "argument mismatch: table expected");
    }
    lua_len(L, 1);
    $1 = lua_tointeger(L, -1);
    $2 = (t_atom *)getbytes($1 * sizeof(t_atom)); //internally calls calloc()

    for (int i=0; i<$1; ++i) {

        lua_pushinteger(L, i+1);
        lua_gettable(L, 1);

        if(lua_isnumber(L, -1)) {

            $2[i].a_type = A_FLOAT;
            $2[i].a_w.w_float = lua_tonumber(L, -1);
        }          
        else if(lua_isstring(L, -1)) {

            $2[i].a_type = A_SYMBOL;
            $2[i].a_w.w_symbol = gensym(lua_tostring(L, -1));
        }
    }
    freebytes($2, $1 * sizeof(t_atom)); //internally calls free()
}

如您所见,我使用 getbytes() 为数组分配内存,它在内部调用 calloc() 并使用 freebytes()<释放内存/code> 内部调用 free().

As you can see, I allocate memory for an array using getbytes() which internally calls calloc() and free the memory using freebytes() which internally calls free().

令人惊讶的是,当我在 Lua 中调用 readTable() 函数时,它运行良好而不会崩溃.

Surprisingly, when I call readTable() function in Lua, it works fine without crashing.

例如,在 Lua 中调用 test.readTable({3, "abc"}) 打印如下结果.

for example, calling test.readTable({3, "abc"}) in Lua prints the following result.

FLOAT : 3
SYMBOL : abc

我的问题是

a) 当我在 SWIG 接口中释放内存时,如何 readTable() 打印结果而不崩溃?也许内存没有被正确释放?

a) How can readTable() print results without crashing when I freed the memory in SWIG interface? Maybe memory is not being properly freed?

b) 如果 a) 没有意义或使用不安全,您是否建议在函数 readTable() 内调用 freebytes() 来代替可以像下面这样吗?

b) If a) doesn't make sense or is not safe to use, would you recommend calling the freebytes() inside the function readTable() instead so it can be like the following?

static void readTable(int argc, t_atom *argv) {

        for (int i=0; i<argc; ++i) {

            if (argv[i].a_type == A_FLOAT)
                post("FLOAT : %g", argv[i].a_w.w_float);
            else if (argv[i].a_type == A_SYMBOL)
                post("SYMBOL : %s", argv[i].a_w.w_symbol->s_name);
        }
        freebytes(argv, argc * sizeof(t_atom));
    }

推荐答案

%typemap(freearg) 是为了.

%include "exception.i"

%typemap(in) (int argc, t_atom *argv) {
    if (!lua_istable(L, $input)) {
        SWIG_exception(SWIG_RuntimeError, "argument mismatch: table expected");
    }
    lua_len(L, $input);
    $1 = lua_tointeger(L, -1);
    $2 = (t_atom *)getbytes($1 * sizeof(t_atom)); // internally calls calloc()

    for (int i = 0; i < $1; ++i) {

        lua_pushinteger(L, i + 1);
        lua_gettable(L, $input);

        if (lua_isnumber(L, -1)) {
            $2[i].a_type = A_FLOAT;
            $2[i].a_w.w_float = lua_tonumber(L, -1);
        } else if (lua_isstring(L, -1)) {
            $2[i].a_type = A_SYMBOL;
            $2[i].a_w.w_symbol = gensym(lua_tostring(L, -1));
        } else {
            SWIG_exception(SWIG_RuntimeError, "unhandled argument type");
        }
    }
}

%typemap(freearg) (int argc, t_atom *argv) {
    freebytes($2, $1 * sizeof(t_atom)); // internally calls free()
}

static void readTable(const std::string &name, int argc, t_atom *argv);

这是 SWIG 3.0 生成的代码

This is the generated code from SWIG 3.0

static int _wrap_readTable(lua_State* L) {
  int SWIG_arg = 0;
  std::string *arg1 = 0 ;
  int arg2 ;
  t_atom *arg3 = (t_atom *) 0 ;

  SWIG_check_num_args("readTable",2,2)
  if(!lua_isuserdata(L,1)) SWIG_fail_arg("readTable",1,"std::string const &");

  if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_std__string,0))){
    SWIG_fail_ptr("readTable",1,SWIGTYPE_p_std__string);
  }

  {
    if (!lua_istable(L, 2)) {
      SWIG_exception(SWIG_RuntimeError, "argument mismatch: table expected");
    }
    lua_len(L, 2);
    arg2 = lua_tointeger(L, -1);
    arg3 = (t_atom *)getbytes(arg2 * sizeof(t_atom)); // internally calls calloc()

    for (int i = 0; i < arg2; ++i) {
      lua_pushinteger(L, i + 1);
      lua_gettable(L, 2);

      if (lua_isnumber(L, -1)) {
        arg3[i].a_type = A_FLOAT;
        arg3[i].a_w.w_float = lua_tonumber(L, -1);
      } else if (lua_isstring(L, -1)) {
        arg3[i].a_type = A_SYMBOL;
        arg3[i].a_w.w_symbol = gensym(lua_tostring(L, -1));
      } else {
        SWIG_exception(SWIG_RuntimeError, "unhandled argument type");
      }
    }
  }
  readTable((std::string const &)*arg1,arg2,arg3);

  {
    freebytes(arg3, arg2 * sizeof(t_atom)); // internally calls free()
  }
  return SWIG_arg;

  if(0) SWIG_fail;

fail:
  {
    freebytes(arg3, arg2 * sizeof(t_atom)); // internally calls free()
  }
  lua_error(L);
  return SWIG_arg;
}

这篇关于在 SWIG 输入类型映射中释放指针数组的正确方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆