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

Wic*_*man 5 c++ python boost boost-python

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

对于python 2项目,我试图将列表gettext-translated字符串作为unicode实例返回给python.gettext()的返回值是一个UTF-8编码的char*,使用PyUnicode_FromString转换为python unicode instrance应该非常简单.我有一种感觉,这是微不足道的,但我似乎无法弄清楚如何.

根据Ignacio Vazquez-Abrams和Thomas KI的评论,确实让这个单线工作; 对于这种情况,您可以绕过所有boost.python基础结构.这是一个例子:

        PyObject* PyMyFunc() {
            const char* txt =  BaseClass::MyFunc();
            return PyUnicode_FromString(txt); 
    }       
Run Code Online (Sandbox Code Playgroud)

暴露在通常的def语句中:

class_<MyCclass>("MyClass")
    .def("MyFunc", &MyClass::PyMyFunc);
Run Code Online (Sandbox Code Playgroud)

不幸的是,当您想要返回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;
}
Run Code Online (Sandbox Code Playgroud)

但这不编译:boost :: python :: list似乎处理PyObject值.

Wic*_*man 2

在 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;
}
Run Code Online (Sandbox Code Playgroud)