Hello, I've realized that one of the C++-classes of my project will be very hard to wrap. Basically, it's a generic container type that holds a pointer to some object (similar to auto_ptr<>). The class is called 'Any' because it can contain a pointer to anything (nice eh? :( ). What I want to do is avoid this class entirely from python, that means, I want to have the wrapped object returned directly without the Any class wrapper. Functions that take an Any as rgument should be callable as well, of course. My question: Is it possible to shado this Any class entirely, and if yes, has this been done or where can I get some hints as to how this could work? I've searched some and my guess is to_python_converter, but I currently don't see the way how to achive my goal. Regards, H.
Hanz Meizer <steam@nurfuerspam.de> writes:
Hello,
I've realized that one of the C++-classes of my project will be very hard to wrap. Basically, it's a generic container type that holds a pointer to some object (similar to auto_ptr<>). The class is called Any' because it can contain a pointer to anything (nice eh? :( ).
Err, like boost::any?
What I want to do is avoid this class entirely from python, that means, I want to have the wrapped object returned directly without the Any class wrapper. Functions that take an Any as rgument should be callable as well, of course.
My question: Is it possible to shado this Any class entirely, and if yes, has this been done or where can I get some hints as to how this could work? I've searched some and my guess is to_python_converter, but I currently don't see the way how to achive my goal.
Good guess. Unfortunately I can't track down the details for you, but here's the gist: you need to register a custom to_python_converter for Any. Then, inside its conversion function, you need to get the typeid of the type stored by the Any (if you can't get that you're out of luck), and invoke the registry's lookup function to get the to-python conversion chain for the stored type. Then you need to "manually" invoke that converter. Expect the resulting code to be fairly ugly and low-level. Sorry :( -- Dave Abrahams Boost Consulting www.boost-consulting.com
Good guess.
Unfortunately I can't track down the details for you, but here's the gist: you need to register a custom to_python_converter for Any. Then, inside its conversion function, you need to get the typeid of the type stored by the Any (if you can't get that you're out of luck), and invoke the registry's lookup function to get the to-python conversion chain for the stored type. Then you need to "manually" invoke that converter. Expect the resulting code to be fairly ugly and low-level. Sorry :(
The Any objects usually contain very basic types, or vectors of very basic types. So I think what would be really nice is to have two functions, one converting an Any object to a PyObject that contains a pythonification of the Any member objects, and another one that gets called with a python object and returns the corresponding Any object. The latter would be used implicitly when a C++ Method is called from python (for example std::string printAny(const Any& car) ). For example: I have a function Any* getProperty() that returns an Any that either conains a vector<double> or a single double. The conversion function then would take the Any, and return a PyObject to python that either contins a list of doubles or a simple double. Unfortunately, diggig through the examples and mailing list archives didn't enlighten me enough, my last test was something like: namespace { struct any_to_python { static PyObject* convert(Any const& x) { std:cerr << "convert called, rejoice!" << endl; exit(1); } }; ... class_< Any, boost::noncopyable >("Any", no_init) ; to_python_converter< Any, any_to_python >(); The intention is to have any_to_python::convert check what is inside of the Any and return the approprioate, constructed python object. Unfortunately, convert is never called. If I uncomment the class_<> ...; thing, python says: No Python class registered for C++ class Any If I sue the class_<>...; thing, I get some error because python tries to call __str__ on the Any object and fails. Help! :) Regards, H.
Hi, Just wanted to notify the list that I found the solution. Besides some other errors I made one of the wrapped functions return_internal_reference. This didn't invoke the to_python_converter I registered, but tried to create a wrapped Any object, where no wrapper was existant of course. I made all functions copy_(non)const_reference and it seems that in this case the to_python_converter get's called all the time. That is reasonable, but I think it should be mentioned in the documentation so that people can check if all their functions use copy_const_reference, bacause if you're new to boost.python there are so many things that can be the cause that you just don't kow where to search H.
Hanz Meizer <steam@nurfuerspam.de> writes:
Hi,
Just wanted to notify the list that I found the solution. Besides some other errors I made one of the wrapped functions return_internal_reference. This didn't invoke the to_python_converter I registered, but tried to create a wrapped Any object, where no wrapper was existant of course. I made all functions copy_(non)const_reference and it seems that in this case the to_python_converter get's called all the time. That is reasonable, but I think it should be mentioned in the documentation
What, specifically?
so that people can check if all their functions use copy_const_reference, bacause if you're new to boost.python there are so many things that can be the cause that you just don't kow where to search
Please propose a patch to the documentation, so I know exactly what you'd like to see explained, and what language you think would've prevented your confusion. -- Dave Abrahams Boost Consulting www.boost-consulting.com
participants (2)
-
David Abrahams -
Hanz Meizer