我有一个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的文件时,这只会发生。
任何想法都将不胜感激。提前谢谢。
答案 0 :(得分:1)
我遇到了与字符串const&amp;相同的问题,似乎Swig从std_string.i添加了一个错误的freearg语句。解决方法是覆盖错误添加的删除:
%typemap(freearg) string const & {}
%typemap(freearg) const myNamespace::myStringType& {}