使用 boost.python 从 UTF-8 编码的 char* 返回 python unicode 实例

发布于 2024-10-18 15:21:14 字数 1095 浏览 2 评论 0原文

我正在尝试做一些应该非常简单的事情,但是我没有太多运气从现有文档中弄清楚如何做。

对于 python 2 项目,我尝试将列表 gettext 翻译的字符串作为 unicode 实例返回给 python。 gettext() 的返回值是 UTF-8 编码的 char*,使用 PyUnicode_FromString 将其转换为 python unicode 实例应该非常简单。我有一种感觉,这很简单,但我似乎不知道如何做。

根据 Ignacio Vazquez-Abrams 和 Thomas KI 的评论,确实可以在单个字符串上实现此功能;在这种情况下,您可以绕过所有 boost.python 基础设施。下面是一个示例:

        PyObject* PyMyFunc() {
            const char* txt =  BaseClass::MyFunc();
            return PyUnicode_FromString(txt); 
    }       

它通过通常的 def 语句公开:

class_<MyCclass>("MyClass")
    .def("MyFunc", &MyClass::PyMyFunc);

不幸的是,当您想要返回 unicode 实例列表时,这不起作用。这是我幼稚的实现:

boost::python::list PyMyFunc() {
    std::vector<std::string> raw_strings = BaseClass::MyFunc();
    std::vector<std::string>::const_iterator i;
    boost::python::list result;

    for (i=raw_strings.begin(); i!=raw_strings.end(); i++)
        result.append(PyUnicode_FromString(i->c_str()));
    return result;
}

但这不能编译:boost::python::list 似乎确实可以处理 PyObject 值。

I'm trying to do something which should be very simple, but I'm not having much luck figuring out how from the existing documentation.

For a python 2 project I am trying to return a list gettext-translated string as a unicode instances to python. The return value for gettext() is a UTF-8 encoded char*, which should be pretty simple to convert to a python unicode instrance using PyUnicode_FromString. I have a feeling this is trivial to do, but I can't seem to figure out how.

Basd on comments from Ignacio Vazquez-Abrams and Thomas K I did get this working for a single string; for that case you can bypass all the boost.python infrastructure. Here is an example:

        PyObject* PyMyFunc() {
            const char* txt =  BaseClass::MyFunc();
            return PyUnicode_FromString(txt); 
    }       

which is exposed with the usual def statement:

class_<MyCclass>("MyClass")
    .def("MyFunc", &MyClass::PyMyFunc);

Unfortuantely this does not work when you want to return a list of unicode instances. This is my naive implementation:

boost::python::list PyMyFunc() {
    std::vector<std::string> raw_strings = BaseClass::MyFunc();
    std::vector<std::string>::const_iterator i;
    boost::python::list result;

    for (i=raw_strings.begin(); i!=raw_strings.end(); i++)
        result.append(PyUnicode_FromString(i->c_str()));
    return result;
}

but this does not compile: boost::python::list does seem to handle PyObject values.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

池予 2024-10-25 15:21:14

在 C++-SIG 邮件列表的帮助下,我现在可以正常工作了。需要两个额外的步骤:

  1. 使用 boost::python::handle<>要在 PyObject* 周围创建一个负责引用处理的 C++ 包装器,
  2. 请使用 boost::python::object 在句柄周围创建一个 C++ 包装器,这允许使用 PyObject* 实例作为(合理的)普通 C++ 类实例,并且因此 boost::python::list 可以处理。

有了这些知识,工作代码如下所示:

boost::python::list PyMyFunc() {
    std::vector<std::string> raw_strings = BaseClass::MyFunc();
    std::vector<std::string>::const_iterator i;
    boost::python::list result;

    for (i=raw_strings.begin(); i!=raw_strings.end(); i++)
        result.append(
             boost::python::object(
               boost::python::handle<>(
                 PyUnicode_FromString(i->c_str()))));
    return result;
}

With some help from the C++-SIG mailinglist I have this working now. There are two extra steps needed:

  1. use boost::python::handle<> to create a C++ wrapper around the PyObject* which takes care of reference handling
  2. use boost::python::object to create a C++ wrapper around the handle, which allows using a PyObject* instance as a (reasonably) normal C++ class instance, and thus something boost::python::list can handle.

With that knowledge the working code looks like this:

boost::python::list PyMyFunc() {
    std::vector<std::string> raw_strings = BaseClass::MyFunc();
    std::vector<std::string>::const_iterator i;
    boost::python::list result;

    for (i=raw_strings.begin(); i!=raw_strings.end(); i++)
        result.append(
             boost::python::object(
               boost::python::handle<>(
                 PyUnicode_FromString(i->c_str()))));
    return result;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文