在SWIG输入typemap中释放指针数组的正确方法? [英] Proper way to free a pointer array in SWIG input typemap?
问题描述
我正在尝试使用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\n", argv[i].a_w.w_float);
else if (argv[i].a_type == A_SYMBOL)
printf("SYMBOL : %s\n", argv[i].a_w.w_symbol->s_name);
}
}
这是我创建的类型图.
%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()
}
如您所见,我使用内部调用calloc()
的getbytes()
为数组分配内存,并使用内部调用free()
的freebytes()
释放内存.
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));
}
推荐答案
That is exactly the situation which %typemap(freearg)
is for.
%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输入typemap中释放指针数组的正确方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!