使用boost.python从UTF-8编码的char*返回python unicode实例
我正在尝试做一件应该很简单的事情,但在现有的文档中找不到太多帮助。
在一个Python 2的项目中,我想把一个经过gettext翻译的字符串列表返回为Python中的unicode实例。gettext()的返回值是一个UTF-8编码的字符指针,这个应该很简单就能用PyUnicode_FromString转换成Python的unicode实例。我觉得这应该很简单,但我就是搞不清楚怎么做。
根据Ignacio Vazquez-Abrams和Thomas K的评论,我确实成功地为单个字符串实现了这一点;在这种情况下,你可以跳过所有的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值。
1 个回答
2
在C++-SIG邮件列表的帮助下,我现在已经搞定了这个。这里有两个额外的步骤:
- 使用 boost::python::handle<> 来创建一个 C++ 的包装器,这个包装器可以处理 PyObject* 的引用问题。
- 使用 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;
}