【问题标题】:python3 C extension module with cp1252 encoded string带有 cp1252 编码字符串的 python3 C 扩展模块
【发布时间】:2019-12-10 11:51:20
【问题描述】:

我正在为现有的 C++ 库编写 Python3 扩展模块,它返回一个似乎采用 cp1252 编码的字符串。 C++ 函数签名是

int get_name(std::string& name);

其中name 是输出变量,其中包含一个字符串,其c_str() 内容如0xb04600,即cp1252 代码页中的DegreeSymbol,后跟大写F,由NULL 字符完成。

在我的python扩展C++代码中,我写了

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 中的一个额外步骤,应该在扩展模块中自动执行。不幸的是,我无法弄清楚如何

【问题讨论】:

  • 我对 Python C API 了解不多,无法为您提供代码,但您不能像您说的那样构建一个 bytes,然后从 C 调用 .decode /i>,通过 Python API,得到你最终的 Python retvalue?
  • @Linuxios - 这正是我想要做的(参见我的更新),但我无法弄清楚 Python 扩展模块 C 的语法。
  • 也许在这个模块周围写一个简单的python包装器,它只会改变编码?

标签: python python-3.x python-extensions cp1252 extension-modules


【解决方案1】:

PyUnicode_Decode 可以为任何standard encoding 完成这项工作,甚至无需先创建bytes 对象。 (您可以使用代码 N 将其传递给 Py_BuildValue 以避免担心引用计数,尽管该技巧并非适用于所有情况。)

【讨论】:

    猜你喜欢
    • 2016-01-11
    • 2015-03-14
    • 1970-01-01
    • 2011-08-13
    • 1970-01-01
    • 2012-01-07
    • 2014-06-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多