【问题标题】:Python C API unicode argumentsPython C API unicode 参数
【发布时间】:2011-12-18 19:23:03
【问题描述】:

我有一个简单的 python 脚本

import _tph
str = u'Привет, <b>мир!</b>' # Some unicode string with a russian characters
_tph.strip_tags(str)

和 C 库,编译成 _tph.so。这是来自它的strip_tags 函数:

PyObject *strip_tags(PyObject *self, PyObject *args) {
    PyUnicodeObject *string;
    Py_ssize_t length;

    PyArg_ParseTuple(args, "u#", &string, &length);
    printf("%d, %d\n", string->length, length);

    // ...
}

printf 函数打印:1080, 19。所以,str 的长度实际上是 19 个符号,但是我从什么地狱得到这 1080 个字符?

当我打印string 时,我得到了我的str、空字符,然后是大量垃圾字节。

垃圾内存如下所示:

u'\u041f\u0440\u0438\u0432\u0435\u0442, \u043c\u0438\u0440!\x00\x00\u0299\Ub7024000\U08c55800\Ub7025904\x00\Ub777358e\Ub777358e \x00\U08c7a0b4\x00\Ub7025904\Ub7025954\Ub702594c\Ub702591c\Ub702592c\Ub7025934\x00\x00\x00

我怎样才能在这里得到一个正常的字符串?

【问题讨论】:

    标签: python c unicode python-c-api


    【解决方案1】:

    这里的“字符串”参数没有很好地命名。它是一个指向 Python Unicode 对象的指针,因此您的 printf 会看到大量二进制数据(对象类型、GC 标头、引用计数和编码的 unicode 代码点),直到它碰巧找到一个 printf 解释的零字节作为字符串的结尾。

    查看字符串的最简单方法是使用PyObject_Print(string)。您可以在以下位置找到用于操作 Python unicode 对象的 C 函数:http://docs.python.org/c-api/unicode.html#unicode-objects

    【讨论】:

    • 事实上,我遇到了这样的代码类型的分段错误:PyObject_Print((PyObject *)string, stdout, 0); 我曾尝试为 GIL 保存线程状态,是的。
    • "string" 被声明为 PyUnicode 对象。要获取该对象,请将解析代码更改为“O”并在结果上使用 PyObject_Print()。或者,将声明更改为 unicode 缓冲区指针并继续使用“u#”。后者为您提供了一个指向计数数组的指针(与 printf 一起使用时不以 null 结尾)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-24
    • 2015-11-02
    • 2014-11-14
    • 2010-12-25
    • 1970-01-01
    • 2015-03-13
    • 2022-11-28
    相关资源
    最近更新 更多