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 添加行以删除不存在的变量的主要内容,如果未能解决你的问题,请参考以下文章

向tableview添加行以添加行和核心数据

向 Dataframe 添加行以统一组的长度

pyqtgraph 动态绘图:添加行以打开 GUI

CSS Grid如何选择行以添加悬停效果?

Cassandra&Spark:我可以将项目添加到行以从行列表创建数据框

在webservice使用者方法中插入行以添加SOAP头