Swig的C ++的char *在Python 3.0中遇到了问题

时间:2010-05-11 03:21:22

标签: python-3.x swig

我们的C ++ lib使用Swig可以很好地处理Python2.4,将C ++ char *返回给python str。但是这个解决方案遇到了Python3.0中的问题,错误是:

Exception =(,UnicodeDecodeError('utf8',b“\ xb6 \ x9d \ xa .....”,0,1,'意外的代码字节')

我们的定义就像(在Python 2.4中正常工作):

void  cGetPubModulus(
 void*  pSslRsa,
    char*  cMod,
    int*   nLen );

%include "cstring.i"
%cstring_output_withsize( char* cMod, int* nLen );

怀疑swig正在自动执行Bytes-> Str转换。在python2.4中它可以是隐式的,但在Python3.0中它不会被允许......任何人都有一个好主意?感谢

2 个答案:

答案 0 :(得分:3)

相反,Python 3可以进行转换。在Python 2中,字节和str是相同的,在Python 3中str是unicode,所以某处某处试图用UTF8将其转换为Unicode,但它不是UTF8。

你的Python 3代码需要返回的不是Python str,而是Python字节。但是,这不适用于Python 2,因此您需要预处理器语句来处理差异。

答案 1 :(得分:3)

我遇到了类似的问题。我为自定义char数组写了一个SWIG类型图(实际上是unsigned char),在使用Python 3时它得到了SEGFAULT。所以我在类型映射中调试了代码,我意识到了Lennart所说的问题。 / p>

我对该问题的解决方案是在该typemap中执行以下操作:

%typemap(in) byte_t[MAX_FONTFACE_LEN] {
   if (PyString_Check($input))
   {
     $1 = (byte_t *)PyString_AsString($input);
   }
   else if  (PyUnicode_Check($input))
   {
     $1 = (byte_t *)PyUnicode_AsEncodedString($input, "utf-8", "Error ~");
     $1 = (byte_t *)PyBytes_AS_STRING($1);
   }
   else
   {
     PyErr_SetString(PyExc_TypeError,"Expected a string.");
     return NULL;
   }
}   

也就是说,我检查了什么类型的字符串对象PyObject。如果函数PyString_AsString()PyUnicode_AsString()的输入分别是UTF-8字符串或Unicode字符串,则它们将返回> 0。如果它是一个Unicode字符串,我们将该字符串转换为调用PyUnicode_AsEncodedString()中的字节,稍后我们将这些字节转换为char *,调用PyBytes_AS_STRING()

请注意,我隐约使用相同的变量来存储unicode字符串并稍后将其转换为字节。尽管存在问题,也许,它可能来自另一个编码风格的讨论,事实是我解决了我的问题。我已经使用python3python2.7二进制文件对其进行了测试,但没有任何问题。

最后,最后一行用于在python调用中复制异常,以通知输入不是字符串,无论是utf还是unicode。