SWIG添加了一些行来删除不存在的变量

时间:2015-07-10 13:56:13

标签: python c++ linux swig

我有一个C ++类,能够以普通的ASCII或宽字符格式输出字符串。我正在使用SWIG(版本3.0.5)来创建Python的绑定。绑定必须在Windows(32位和64位)和Linux(64位)下运行。我编写了一个自定义类型映射来从Python获取字符串到我的C ++类:/这个typemap用于从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"

当这些包含文件与上面的typemap一起使用时,我们会在代码中插入虚假的代码行,如下所示:

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。

有谁知道为什么会这样?我相信我的typemap必须有一个错误,它会产生额外的代码行,但同样,当SWIG包含包含宽字符iostreams的文件时,这只会发生。

任何想法都将不胜感激。提前谢谢。

1 个答案:

答案 0 :(得分:1)

我遇到了与字符串const&amp;相同的问题,似乎Swig从std_string.i添加了一个错误的freearg语句。解决方法是覆盖错误添加的删除:

%typemap(freearg) string const & {}
%typemap(freearg) const myNamespace::myStringType& {}