我正在为现有的C 库编写Python3扩展模块,该模块返回似乎在CP1252编码中的字符串。C 函数签名为
int get_name(std::string& name);
其中name
是包含一个带有C_STR((内容的字符串的输出变量,例如0xB04600,它是CP1252代码页中的degreesymbol,其后是上案例F
,由null字符完成。
在我的Python扩展中,我写了
std::string name;
int retval = get_value(name);
py_retval = Py_BuildValue((char *) "is#", retval, (name).c_str(), (name).size());
但是,这会导致以下运行时异常
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb0 in position 0: invalid start byte
我将cp2152的字符串返回python的正确方法是什么?
更新我发现,如果我使用y#
而不是s#
从扩展程序中返回Python字节对象,那么我可以将该字节对象转换为使用.decode('cp1252')
中的Python代码中的字符串。但是,这是Python中应在扩展模块中自动化的额外步骤。不幸的是,我无法弄清楚
PyUnicode_Decode
可以为任何标准编码执行此作业,甚至不必先制作bytes
对象。(您可以使用代码N
将其传递给Py_BuildValue
,以避免担心参考计数,尽管该技巧在所有情况下都不适用。(