[C++-sig] sending a c++ class to a python function
Jim Bosch
talljimbo at gmail.com
Mon Aug 29 20:08:23 CEST 2011
Normally a to-python converter is needed when you have a function that
returns a C++ object, and you want to wrap that function so the returned
thing can be used in Python. I don't see any functions that return a
Scene object. They will also enable expressions of the form
"object(scene)", but you can't use that sort of expression to define the
converter itself.
When you're writing the conversion function, remember that Boost.Python
really doesn't know anything about your class unless you tell it about
it using a boost::python::class_ definition, and doing that will already
define a to-python converter for it. The instructions you're following
are for things like strings that already have a Python type they can be
converted to; you probably want to use class_ for something like Scene.
Now, if you just wanted to convert Scene to a dict instead of having a
Scene type in Python, a custom conversion would indeed be the way to go,
but you'd need to create a dict and fill it in the convert function.
Anyhow, my best guess for the segfault is that you have an infinite
recursion - when you call object(scene), it needs to look for a
to-python converter in the registry. So it finds yours, which calls
object(scene). Repeat.
Jim
On 08/28/2011 08:22 PM, Josh Stratton wrote:
> I'm getting an error when I try to pass down my object that results in
> a seg fault. I've registered my class I'm sending down, but when I
> actually send it, my program exits at this line in the library right
> after I call the importFile() function...
>
> return call<obj>(get_managed_object(self, tag),
> BOOST_PP_ENUM_PARAMS_Z(1, N, a));
>
> // here's the class I'm trying to send down
> class Scene
> {
> public:
> MeshP mesh(int key);
> void clearScene();
> CameraP createCamera(QString name);
> MeshP createMesh(QString name);
> void setMesh(int meshKey, MeshP mesh) {
> _meshes[meshKey] = mesh; }
> QHashIterator<int, MeshP> meshes() { return
> QHashIterator<int,MeshP>(_meshes); }
> QHashIterator<int, CameraP> cameras() { return
> QHashIterator<int,CameraP>(_cameras); }
> CameraP fetchCamera(QString name);
> QList<QString> importExtensions();
> void importFile(QString fileName);
> void evalPythonFile(QString fileName);
> Scene();
> protected:
> int uniqueCameraKey();
> int uniqueMeshKey();
> QString uniqueName(QString prefix);
>
> private:
> QHash<int,MeshP> _meshes;
> QHash<int,CameraP> _cameras;
> //QHash<int,Light*> _lights;
> QSet<QString> _names;
> // PythonQtObjectPtr _context;
> object _pyMainModule;
> object _pyMainNamespace;
> public slots:
> void pythonStdOut(const QString&s)
> { std::cout<< s.toStdString()<< std::flush; }
> void pythonStdErr(const QString&s)
> { std::cout<< s.toStdString()<< std::flush; }
> };
>
> // first I create the mapping, which I'm not sure is correct, trying
> to follow: http://misspent.wordpress.com/2009/09/27/how-to-write-boost-python-converters/
> struct SceneToPython
> {
> static PyObject* convert(Scene const& scene)
> {
> return boost::python::incref(boost::python::object(scene).ptr());
> }
> };
>
> // then I register it
> boost::python::to_python_converter<Scene,SceneToPython>();
>
> // then I send it down from inside my Scene object
> try {
> object processFileFunc =
> _pyMainModule.attr("MeshImporter").attr("processFile");
> processFileFunc(this, fileName); // seems to error here
> } catch (boost::python::error_already_set const&) {
> QString perror = parse_python_exception();
> std::cerr<< "Error in Python: "<< perror.toStdString()<< std::endl;
> }
>
> I'm not really sure what actually is wrong besides something being
> setup incorrectly. Do I need to make a python-to-C++ converter as
> well even if I'm not sending it back to C++? Or is my convert()
> function just improperly implemented? I wasn't sure how much I need
> to actually get it to map correctly. Thanks.
> _______________________________________________
> Cplusplus-sig mailing list
> Cplusplus-sig at python.org
> http://mail.python.org/mailman/listinfo/cplusplus-sig
More information about the Cplusplus-sig
mailing list