[英]Using Unicode in Boost Python with a C++ function that takes std::wstring
I am using the Boost Python library to wrap a C++ class I have so that I can call its methods from Python. 我正在使用Boost Python库来包装我拥有的C ++类,以便我可以从Python调用它的方法。 My C++ class Clazz
has public methods: 我的C ++类Clazz
有公共方法:
void doSomething(std::string& s) { ... }
void doSomethingWide(std::wstring& ws) { ... }
I've created a BOOST_PYTHON_MODULE
which points to these two methods. 我创建了一个指向这两种方法的BOOST_PYTHON_MODULE
。 The first one which uses std::string
I'm able to call fine. 第一个使用std::string
我可以调用。 However, when I try to call the second one with a Python Unicode string: 但是,当我尝试使用Python Unicode字符串调用第二个时:
x = u'hello'
Clazz.doSomethingWide(x)
I get the error: 我收到错误:
ArgumentError: Python argument types in Clazz.doSomethingWide(Clazz, unicode) did not match C++ signature: doSomething(Clazz, std::wstring)
I had hoped that unicode
would automatically interface with std::wstring
as the regular Python string type did with std::string
. 我曾希望unicode
会自动与std::wstring
接口,因为常规的Python字符串类型与std::string
。 However, this appears to not be the case. 但是,情况似乎并非如此。
In another thread, someone suggested first doing the conversion: 在另一个帖子中,有人建议先进行转换:
x = str(x.encode('utf-8'))
However, I am dealing with very large strings and this destroys the performance of my code since it is O(n) in the number of characters of x
. 但是,我正在处理非常大的字符串,这会破坏我的代码的性能,因为它是x
的字符数O(n) 。
I do have the ability to modify the C++ library that I'm trying to interface with. 我有修改,我试图与接口的C ++库的能力。 Is there a way to pass in Python unicode
types into my C++ library in a way that I can use them? 有没有办法以我可以使用它的方式将Python unicode
类型传递到我的C ++库中? I've searched the Internet far and wide and found some references to converters and other things, but implementing them did not fix the above error message (very possibly I'm not using them correctly). 我已经远程搜索了互联网,并发现了一些转换器和其他东西的引用,但实现它们并没有修复上面的错误信息(很可能我没有正确使用它们)。
In short, type conversions generally result in rvalue objects, and thus the parameters must either accept by value or by const reference. 简而言之,类型转换通常会产生rvalue对象,因此参数必须通过值或const引用接受。 Hence, change: 因此,改变:
void doSomethingWide(std::wstring&);
to either of the following: 以下任一项:
void doSomethingWide(std::wstring);
void doSomethingWide(const std::wstring&);
Boost.Python added std::wstring
conversions on 11-SEP-2003. Boost.Python在11-SEP-2003上添加了std::wstring
转换 。 As a general rule, when type conversions occur in Boost.Python, the resulting object is treated as an rvalue. 作为一般规则,当在Boost.Python中发生类型转换时,结果对象将被视为右值。 This behavior is indirectly noted in the boost::python::extract
observer specification: 在boost::python::extract
观察者规范中间接注意到此行为:
Converts the stored pointer to
result_type
, which is eitherT
orT const&
. 将存储的指针转换为result_type
,它是T
或T const&
。
If lvalue conversions were supported, it could introduce awkward semantics for some types. 如果支持左值转换,则可能会为某些类型引入笨拙的语义。 For example, immutable Python strings could be modified by C++ functions. 例如,C ++函数可以修改不可变的Python字符串。
Here is a complete minimal example: 这是一个完整的最小例子:
#include <iostream>
#include <string>
#include <boost/python.hpp>
class spam
{
public:
void doSomething(const std::string& str)
{
std::cout << "spam::doSomething(): " << str << std::endl;
}
void doSomethingWide(const std::wstring& str)
{
std::wcout << "spam::doSomethingWide(): " << str << std::endl;
}
};
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
python::class_<spam>("Spam")
.def("doSomething", &spam::doSomething)
.def("doSomethingWide", &spam::doSomethingWide)
;
}
Interactive usage: 互动用法:
>>> import example
>>> spam = example.Spam()
>>> spam.doSomething("test")
spam::doSomething(): test
>>> spam.doSomethingWide(u"test")
spam::doSomethingWide(): test
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.