在 SWIG in 和 freearg 类型映射之间传递信息
Passing information between SWIG in and freearg typemaps
我有一个针对 Python 的类型映射,它接受一个已经包装的指针对象或另外允许传递一个 Python 序列。在包装指针的情况下,我不想删除 SWIG 拥有的内存。但是,在处理序列时,我正在分配一个需要删除的临时对象。所以我在我的 'in' 类型映射中添加了一个标志来标记我是否分配了指针目标。如何在相应的 'freearg' 类型映射中访问此标志?
类型映射如下所示:
%typemap(in) name* (void* argp = 0, int res = 0, bool needsDelete = false) {
res = SWIG_ConvertPtr($input, &argp, $descriptor, $disown | 0);
if (SWIG_IsOK(res)) {
= ($ltype)(argp); // already a wrapped pointer, accept
} else {
if (!PySequence_Check($input)) {
SWIG_exception(SWIG_ArgError(res), "Expecting a sequence.");
} else if (PyObject_Length($input) != size) {
SWIG_exception(SWIG_ArgError(res), "Expecting a sequence of length " #size);
} else {
needsDelete = true;
= new name;
for (int i = 0; i < size; ++i) {
PyObject* o = PySequence_GetItem($input, i);
(*)[i] = swig::as<type>(o);
Py_DECREF(o);
}
}
}
}
%typemap(freearg) name* {
if ( /* && needsDelete */) delete ;
}
这导致生成的代码如下所示:
{
res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_MyName_t, 0 | 0);
if (SWIG_IsOK(res2)) {
arg2 = (MyName *)(argp2); // already a wrapper pointer, accept
} else {
if (!PySequence_Check(obj1)) {
SWIG_exception(SWIG_ArgError(res2), "Expecting a sequence.");
} else if (PyObject_Length(obj1) != 3) {
SWIG_exception(SWIG_ArgError(res2), "Expecting a sequence of length ""3");
} else {
needsDelete2 = true;
arg2 = new MyName;
for (int i = 0; i < 3; ++i) {
PyObject* o = PySequence_GetItem(obj1, i);
(*arg2)[i] = swig::as<double>(o);
Py_DECREF(o);
}
}
}
}
if (arg1) (arg1)->someMember = *arg2;
resultobj = SWIG_Py_Void();
{
if (arg2 /* && needsDelete */) delete arg2;
}
根据 SWIG 手册中的 11.15 Passing data between typemaps:
您只需要在 freearg 类型映射中将变量用作 needsDelete$argnum
。
我有一个针对 Python 的类型映射,它接受一个已经包装的指针对象或另外允许传递一个 Python 序列。在包装指针的情况下,我不想删除 SWIG 拥有的内存。但是,在处理序列时,我正在分配一个需要删除的临时对象。所以我在我的 'in' 类型映射中添加了一个标志来标记我是否分配了指针目标。如何在相应的 'freearg' 类型映射中访问此标志?
类型映射如下所示:
%typemap(in) name* (void* argp = 0, int res = 0, bool needsDelete = false) {
res = SWIG_ConvertPtr($input, &argp, $descriptor, $disown | 0);
if (SWIG_IsOK(res)) {
= ($ltype)(argp); // already a wrapped pointer, accept
} else {
if (!PySequence_Check($input)) {
SWIG_exception(SWIG_ArgError(res), "Expecting a sequence.");
} else if (PyObject_Length($input) != size) {
SWIG_exception(SWIG_ArgError(res), "Expecting a sequence of length " #size);
} else {
needsDelete = true;
= new name;
for (int i = 0; i < size; ++i) {
PyObject* o = PySequence_GetItem($input, i);
(*)[i] = swig::as<type>(o);
Py_DECREF(o);
}
}
}
}
%typemap(freearg) name* {
if ( /* && needsDelete */) delete ;
}
这导致生成的代码如下所示:
{
res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_MyName_t, 0 | 0);
if (SWIG_IsOK(res2)) {
arg2 = (MyName *)(argp2); // already a wrapper pointer, accept
} else {
if (!PySequence_Check(obj1)) {
SWIG_exception(SWIG_ArgError(res2), "Expecting a sequence.");
} else if (PyObject_Length(obj1) != 3) {
SWIG_exception(SWIG_ArgError(res2), "Expecting a sequence of length ""3");
} else {
needsDelete2 = true;
arg2 = new MyName;
for (int i = 0; i < 3; ++i) {
PyObject* o = PySequence_GetItem(obj1, i);
(*arg2)[i] = swig::as<double>(o);
Py_DECREF(o);
}
}
}
}
if (arg1) (arg1)->someMember = *arg2;
resultobj = SWIG_Py_Void();
{
if (arg2 /* && needsDelete */) delete arg2;
}
根据 SWIG 手册中的 11.15 Passing data between typemaps:
您只需要在 freearg 类型映射中将变量用作 needsDelete$argnum
。