[C++-sig] sending a c++ class to a python function

Jim Bosch talljimbo at gmail.com
Tue Aug 30 19:57:12 CEST 2011


On 08/30/2011 07:45 AM, Josh Stratton wrote:
> Oh, okay.  So I can create a module...
>
> #include "scene.h"
> BOOST_PYTHON_MODULE(scene)
> {
>      class_<Scene>("Scene");
> }
>
> and then import it (even though) in my python I normally don't import
> things I'm not creating.  I'm assuming this is a boost-python thing to
> get the class into scope, which gets rid of the "converter found for
> C++ type: Scene" error.

I don't really understand what you mean; if you want to use code that 
was defined in another Python module, you always have to import it. 
It's just that in this case the module happens to be written in C++.

> from scene import Scene # in my python code
>
> In my terminal I get...
>
> Error in Python:<class 'Boost.Python.ArgumentError'>: Python argument types in
>      Mesh.buildByIndex(Scene, PrimitiveParts)
> did not match C++ signature:
>      buildByIndex(QSharedPointer<Scene>, PrimitiveParts):   File
> "<string>", line 21, in processFile
>
> for this function:
>
>      static void                  buildByIndex(SceneP scene,
> PrimitiveParts parts);
>
> The function I'm calling has SceneP typedeffed as a
> QSharedPointer<Scene>  and I'm assuming this error is because I haven't
> made a Scene to QSharedPointer<Scene>  converter, which should just
> wrap the Scene object when it comes in requiring a custom conversion
> function.

This is another case where you probably want to use something other than 
a custom converter (and if you did use a custom converter, you'd want a 
from-python lvalue converter, not a to-python converter, anyways, and 
those are defined differently).

What you probably want to do is tell Boost.Python that QSharedPointer is 
a smart pointer, and tell it to wrap your Scene objects inside one (at 
least if you're going to have to deal with them a lot).

To do that, you'll want to specialize boost::python::pointee and provide 
a get_pointer function:

namespace boost { namespace python {

template <typename T>
struct pointee< QSharedPointer<T> > {
     typedef T type;
};

}}

// in some namespace where ADL will find it...
template <typename T*>
inline Scene * get_pointer(QSharedPointer<T> const & p) {
     return p.get(); // or whatever
}

Then, when you define the class, use:

class_< Scene, QSharedPointer<Scene> >(...)

You can find more information in the reference documentation:

http://www.boost.org/doc/libs/1_47_0/libs/python/doc/v2/class.html#classes

Good Luck!

Jim


More information about the Cplusplus-sig mailing list