SWIG 添加行以删除不存在的变量
Posted
技术标签:
【中文标题】SWIG 添加行以删除不存在的变量【英文标题】:SWIG adds lines to delete variables that don't exist 【发布时间】:2015-07-10 13:56:13 【问题描述】:我有一个能够以普通 ASCII 或宽字符格式输出字符串的 C++ 类。我正在使用 SWIG(版本 3.0.5)为 Python 创建绑定。绑定必须在 Windows(32 位和 64 位)和 Linux(64 位)下工作。我已经编写了一个自定义类型映射来将字符串从 Python 获取到我的 C++ 类:/此类型映射用于将字符串从 Python 获取到 C++ 类
%typemap(in) const myNamespace::myStringType&
// Custom input conversion #7
const char* pChars = "";
PyObject* pyobj = $input;
if(PyString_Check(pyobj))
pChars = PyString_AsString( pyobj );
$1 = new myNamespace::myStringType( pChars );
else if (PyUnicode_Check( pyobj ))
PyObject* tmp = PyUnicode_AsUTF8String( pyobj );
pChars = PyString_AsString( tmp );
$1 = new myNamespace::myStringType( pChars );
else
std::string strTemp;
int rrr = SWIG_ConvertPtr(pyobj, (void **) &strTemp, $descriptor(String), 0);
if (!SWIG_IsOK(rrr))
SWIG_exception_fail(SWIG_ArgError(rrr), "Expected a String "
"in method '$symname', argument $argnum of type '$type'");
$1 = new myNamespace::myStringType( strTemp );
此类型映射适用于 32 位和 64 位普通字符构建,但是当我尝试构建宽字符时会出现问题。在宽字符构建中,我需要在我的界面文件中包含以下 SWIG 包含文件:
%include "std_wiostream.i"
%include "std_wsstream.i"
当这些包含文件与上述类型映射一起使用时,我们会在包装器中插入虚假代码行,如下所示:
if (SWIG_IsNewObj(res2)) delete arg2;
这是一个由 SWIG 生成的完整包装函数的示例:
SWIGINTERN PyObject *_wrap_timeStampFromStr(PyObject *SWIGUNUSEDPARM(self), PyObject *args)
PyObject *resultobj = 0;
myNamespace::myStringType *arg1 = 0 ;
PyObject * obj0 = 0 ;
slx::SlxU64 result;
if (!PyArg_ParseTuple(args,(char *)"O:timeStampFromStr",&obj0)) SWIG_fail;
// Custom input conversion #7
const char* pChars = "";
PyObject* pyobj = obj0;
if(PyString_Check(pyobj))
pChars = PyString_AsString( pyobj );
arg1 = new myNamespace::myStringType( pChars );
else if (PyUnicode_Check( pyobj ))
PyObject* tmp = PyUnicode_AsUTF8String( pyobj );
pChars = PyString_AsString( tmp );
arg1 = new myNamespace::myStringType( pChars );
else
std::string strTemp;
int rrr = SWIG_ConvertPtr(pyobj, (void **) &strTemp, SWIGTYPE_String, 0);
if (!SWIG_IsOK(rrr))
SWIG_exception_fail(SWIG_ArgError(rrr), "Expected a String "
"in method 'timeStampFromStr', argument 1 of type 'myNamespace::myStringType const &'");
arg1 = new myNamespace::myStringType( strTemp );
result = (slx::SlxU64)slx::timeStampFromStr((std::basic_string< char,std::char_traits< char >,std::allocator< char > > const &)*arg1);
resultobj = SWIG_From_unsigned_SS_long_SS_long(static_cast< unsigned long long >(result));
if (SWIG_IsNewObj(res2)) delete arg2;
return resultobj;
fail:
if (SWIG_IsNewObj(res2)) delete arg2;
return NULL;
代码无法编译,因为 res2 和 arg2 变量从未在包装代码中定义。
如果我省略了 SWIG 包含的内容,多余的代码行就会消失,但我将无法获得所需的宽字符 iostream 支持。
目前的解决方法是手动删除这些代码行,但显然这不适用于 Windows 中的自动构建和 Linux 中的 Makefile。
有人知道为什么会这样吗?我相信我的类型映射中一定有一个错误,它会产生额外的代码行,但同样,只有当包含宽字符 iostream 的 SWIG 包含文件时才会发生这种情况。
任何想法将不胜感激。提前致谢。
【问题讨论】:
我在两个案例中遇到过类似的事情。第一种情况是因为应用了多个类型映射。另一种情况是因为我缺少一些 %includes。尝试制作一个准系统示例,仅将一个类型映射应用于具有给定原型的函数,并发布一个带有内联源的 .i 文件 【参考方案1】:我对 string const & 也有同样的问题,似乎 Swig 从 std_string.i 添加了错误的 freearg 语句。解决方法是覆盖错误添加的删除:
%typemap(freearg) string const &
%typemap(freearg) const myNamespace::myStringType&
【讨论】:
以上是关于SWIG 添加行以删除不存在的变量的主要内容,如果未能解决你的问题,请参考以下文章