J'ai mon own string class et je veux l'exporter en python (avec boost.python) et l'utiliser comme une chaîne native. J'ai écrit des convertisseurs pour cela.Utilisation de la chaîne propre
Le premier est l'exportation de ma chaîne:
bp::class_<CL_StringRef8>("CL_StringRef8", bp::init<const std::string&>())
.def("CStr", &CL_StringRef8::c_str);
Les convertisseurs sont de tutoriel par défaut, mais avec mon type:
// CL_StringRef8 → Python string --------------------------------------
struct cl_stringref8_to_python_str
{
static PyObject* convert(CL_StringRef8 const& s)
{
return boost::python::incref(boost::python::object(s.c_str()).ptr());
}
};
// Python string → CL_StringRef8 --------------------------------------
struct cl_stringref8_from_python_str
{
cl_stringref8_from_python_str()
{
bp::converter::registry::push_back(
&convertible,
&construct,
boost::python::type_id<CL_StringRef8>()
);
}
static void* convertible(PyObject* obj_ptr)
{
if (!PyString_Check(obj_ptr)) return 0;
return obj_ptr;
}
static void construct(PyObject* obj_ptr, bp::converter::rvalue_from_python_stage1_data* data)
{
const char* value = PyString_AsString(obj_ptr);
if (value == 0) bp::throw_error_already_set();
void* storage = ((bp::converter::rvalue_from_python_storage<CL_StringRef8>*)data)->storage.bytes;
new (storage) CL_StringRef8(value);
data->convertible = storage;
}
};
Maintenant, ce que je comprends, je peux appeler c fonctions ++ de python qui prend en arguments CL_StringRef8
, mais j'ai un code:
print GetMyStringObject()
data = float(GetMyStringObject())
# ==>
<CL_StringRef object at 0x7fd15dfd9de8>
TypeError: float() argument must be a string or a number
Comme je comprends que je doivent exporter str()
méthode de CL_StringRef8
mais je ne peux pas le faire:
bp::class_<CL_StringRef8>("CL_StringRef8", bp::init<const std::string&>())
.def("CStr", &CL_StringRef8::c_str)
.def(bp::self_ns::str(bp::self_ns::self));
La dernière ligne appelle une erreur:
/usr/include/boost/lexical_cast.hpp: In member function ‘bool boost::detail::lexical_stream<Target, Source, Traits>::operator<<(const Source&) [with Target = std::basic_string<char>, Source = CL_StringRef8, Traits = std::char_traits<char>]’:
/usr/include/boost/lexical_cast.hpp:1151:13: instantiated from ‘Target boost::detail::lexical_cast(typename boost::call_traits<Source>::param_type, CharT*, std::size_t) [with Target = std::basic_string<char>, Source = CL_StringRef8, bool Unlimited = true, CharT = char, typename boost::call_traits<Source>::param_type = const CL_StringRef8&, std::size_t = long unsigned int]’
/usr/include/boost/lexical_cast.hpp:1174:77: instantiated from ‘Target boost::lexical_cast(const Source&) [with Target = std::basic_string<char>, Source = CL_StringRef8]’
/usr/include/boost/python/operators.hpp:357:1: instantiated from ‘static PyObject* boost::python::detail::operator_1<(boost::python::detail::operator_id)19u>::apply<T>::execute(boost::python::detail::operator_1<(boost::python::detail::operator_id)19u>::apply<T>::self_t&) [with T = CL_StringRef8, PyObject = _object, boost::python::detail::operator_1<(boost::python::detail::operator_id)19u>::apply<T>::self_t = CL_StringRef8]’
/usr/include/boost/python/operators.hpp:152:11: instantiated from ‘void boost::python::detail::operator_<id, L, R>::visit(ClassT&) const [with ClassT = boost::python::class_<CL_StringRef8>, boost::python::detail::operator_id id = (boost::python::detail::operator_id)19u, L = boost::python::detail::not_specified, R = boost::python::detail::not_specified]’
/usr/include/boost/python/def_visitor.hpp:31:9: instantiated from ‘static void boost::python::def_visitor_access::visit(const V&, classT&) [with V = boost::python::def_visitor<boost::python::detail::operator_<(boost::python::detail::operator_id)19u> >, classT = boost::python::class_<CL_StringRef8>]’
/usr/include/boost/python/def_visitor.hpp:67:9: instantiated from ‘void boost::python::def_visitor<DerivedVisitor>::visit(classT&) const [with classT = boost::python::class_<CL_StringRef8>, DerivedVisitor = boost::python::detail::operator_<(boost::python::detail::operator_id)19u>]’
/usr/include/boost/python/class.hpp:225:9: instantiated from ‘boost::python::class_<T, X1, X2, X3>::self& boost::python::class_<T, X1, X2, X3>::def(const boost::python::def_visitor<Derived>&) [with Derived = boost::python::detail::operator_<(boost::python::detail::operator_id)19u>, W = CL_StringRef8, X1 = boost::python::detail::not_specified, X2 = boost::python::detail::not_specified, X3 = boost::python::detail::not_specified, boost::python::class_<T, X1, X2, X3>::self = boost::python::class_<CL_StringRef8>]’
/home/ockonal/Workspace/Themisto/src/Scripts/Core/TypesConverters.cpp:375:49: instantiated from here
/usr/include/boost/lexical_cast.hpp:595:48: error: cannot bind ‘std::basic_ostream<char>’ lvalue to ‘std::basic_ostream<char>&&’
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../../include/c++/4.6.0/ostream:581:5: error: initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char, _Traits = std::char_traits<char>, _Tp = CL_StringRef8]’
ps et oui, je ne pas oublier enregistrer mes convertisseurs en python.
Intéressant ce qui n'allait pas avec 'std :: basic_string' que votre classe fait mieux? Si vous ne pouvez pas affecter votre chaîne à 'std :: string', vous ne pouvez pas utiliser des implémentations telles que' boost :: lexical_cast' avec votre classe de chaînes. Vous devrez fournir une compatibilité avec les algorithmes STL, les itérateurs, etc. ainsi que les conversions. – AJG85