我们的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中它不会被允许......任何人都有一个好主意?感谢
答案 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字符串并稍后将其转换为字节。尽管存在问题,也许,它可能来自另一个编码风格的讨论,事实是我解决了我的问题。我已经使用python3
和python2.7
二进制文件对其进行了测试,但没有任何问题。
最后,最后一行用于在python调用中复制异常,以通知输入不是字符串,无论是utf还是unicode。