C++ 使用boost.python从UTF-8编码字符*返回python unicode实例

C++ 使用boost.python从UTF-8编码字符*返回python unicode实例,c++,python,boost,boost-python,C++,Python,Boost,Boost Python,我正在尝试做一些应该非常简单的事情,但是我没有太多的运气从现有的文档中弄清楚如何做 对于Python2项目,我试图将一个列表gettext翻译字符串作为unicode实例返回给python。gettext()的返回值是一个UTF-8编码的字符*,使用PyUnicode_FromString将其转换为python unicode指令应该非常简单。我有一种感觉,这是微不足道的事,但我似乎不知道怎么做 根据伊格纳西奥·巴斯克斯·艾布拉姆斯(Ignacio Vazquez Abrams)和托马斯·K的评

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

对于Python2项目,我试图将一个列表gettext翻译字符串作为unicode实例返回给python。gettext()的返回值是一个UTF-8编码的字符*,使用PyUnicode_FromString将其转换为python unicode指令应该非常简单。我有一种感觉,这是微不足道的事,但我似乎不知道怎么做

根据伊格纳西奥·巴斯克斯·艾布拉姆斯(Ignacio Vazquez Abrams)和托马斯·K的评论,我确实在一根弦上实现了这一点;在这种情况下,您可以绕过所有boost.python基础结构。以下是一个例子:

        PyObject* PyMyFunc() {
            const char* txt =  BaseClass::MyFunc();
            return PyUnicode_FromString(txt); 
    }       
它与通常的def语句一起公开:

class_<MyCclass>("MyClass")
    .def("MyFunc", &MyClass::PyMyFunc);
类(“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 PyMyFunc(){
std::vector raw_strings=BaseClass::MyFunc();
std::vector::const_迭代器i;
boost::python::list结果;
for(i=raw_strings.begin();i!=raw_strings.end();i++)
append(PyUnicode_FromString(i->c_str());
返回结果;
}

但是这并没有编译:boost::python::list似乎确实可以处理PyObject值。

在C++-SIG mailinglist的帮助下,我现在可以使用它了。需要另外两个步骤:

  • 使用Booo::Python::句柄,在PyObjt *上创建C++包装器,它负责引用处理< /LI>
  • 使用Booo::Python::对象在句柄周围创建一个C++包装器,它允许使用pyObjas*实例作为(合理的)普通C++类实例,从而有一些Booo::PythOn::列表可以处理.< /LI> 有了这些知识,工作代码如下所示:

    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;
    }
    
    boost::python::list PyMyFunc(){
    std::vector raw_strings=BaseClass::MyFunc();
    std::vector::const_迭代器i;
    boost::python::list结果;
    for(i=raw_strings.begin();i!=raw_strings.end();i++)
    result.append(
    boost::python::object(
    boost::python::handle(
    PyUnicode_FromString(i->c_str());
    返回结果;
    }
    
    我不明白。只调用
    PyUnicode\u FromString()
    有什么不对?主要是因为它可以工作。例如,使用一个简单的包装器方法返回PyUnicodeFromString(BaseClass::method()),或者在从python调用时导致None或错误。您是否尝试找出错误所在?错误可能在别处吗?字符串是否有可能不是有效的UTF-8?编码确实是一个重要因素:我不希望gettext根据当前语言环境切换编码。通过添加对
    bind\u textdomain\u codeset()
    的调用来强制UTF-8输出,实现了这一点。简单的PyUnicode\u FromString现在确实可以用于单个字符串。但是,当我不得不返回unicode实例列表时,我仍然在挣扎;我更新了这个问题,以更好地反映我的用例,并根据您的评论为单个unicode返回值添加了一个工作示例。