Here's a really short example of what I don't understand. Basically I can setup the python function to accept shared pointers, but can I setup it to also use normal pointers? In the example code attached, if I uncomment scene->sendYourselfToPython(); it fails because it's using "this" as the scene pointer.
Error in Python: <type 'exceptions.TypeError'>: No to_python (by-value) converter found for C++ type: Scene So it appears to only work for shared pointers at this point. Can I also get it to work with "this" at the same time? Jim pointed me to "enable_shared_from_this" as a way for creating a shared pointer object, which makes sense from the docs of how to do it, but I was wondering if I necessarily NEED to send it down as a shared pointer. Thanks http://dpaste.com/607969/ OR #include <iostream> #include <boost/python.hpp> #include <boost/python/class.hpp> #include <boost/python/module.hpp> #include <boost/python/def.hpp> using namespace boost::python; object pyMainModule; object pyMainNamespace; #define EXAMPLE_PY_FUNCTION \ "from scene import Scene\n" \ "class Foo(object):\n" \ " @staticmethod\n" \ " def processFile(scene, filename):\n" \ " print('here')\n" std::string parse_python_exception(); class Scene { public: void sendYourselfToPython() { try { object ignored = exec(EXAMPLE_PY_FUNCTION, pyMainNamespace); object processFileFunc = pyMainModule.attr("Foo").attr("processFile"); processFileFunc(this, "test.txt"); } catch (boost::python::error_already_set const &) { std::string perror = parse_python_exception(); std::cerr << "Error in Python: " << perror << std::endl; } } }; typedef boost::shared_ptr<Scene> SceneP; BOOST_PYTHON_MODULE(scene) { class_<Scene, boost::noncopyable>("Scene"); } main(int argc, char**argv) { std::cout << "starting program..." << std::endl; Py_Initialize(); pyMainModule = import("__main__"); pyMainNamespace = pyMainModule.attr("__dict__"); boost::python::register_ptr_to_python< boost::shared_ptr<Scene> >(); PyImport_AppendInittab("scene", &initscene); SceneP scene(new Scene()); scene->sendYourselfToPython(); // confused here try { object ignored = exec(EXAMPLE_PY_FUNCTION, pyMainNamespace); object processFileFunc = pyMainModule.attr("Foo").attr("processFile"); processFileFunc(scene, "test.txt"); } catch (boost::python::error_already_set const &) { std::string perror = parse_python_exception(); std::cerr << "Error in Python: " << perror << std::endl; } } // taken from http://thejosephturner.com/blog/2011/06/15/embedding-python-in-c-applications-with-boostpython-part-2/ namespace py = boost::python; std::string parse_python_exception() { PyObject *type_ptr = NULL, *value_ptr = NULL, *traceback_ptr = NULL; PyErr_Fetch(&type_ptr, &value_ptr, &traceback_ptr); std::string ret("Unfetchable Python error"); if (type_ptr != NULL) { py::handle<> h_type(type_ptr); py::str type_pstr(h_type); py::extract<std::string> e_type_pstr(type_pstr); if(e_type_pstr.check()) ret = e_type_pstr(); else ret = "Unknown exception type"; } if (value_ptr != NULL) { py::handle<> h_val(value_ptr); py::str a(h_val); py::extract<std::string> returned(a); if(returned.check()) ret += ": " + returned(); else ret += std::string(": Unparseable Python error: "); } if (traceback_ptr != NULL) { py::handle<> h_tb(traceback_ptr); py::object tb(py::import("traceback")); py::object fmt_tb(tb.attr("format_tb")); py::object tb_list(fmt_tb(h_tb)); py::object tb_str(py::str("\n").join(tb_list)); py::extract<std::string> returned(tb_str); if(returned.check()) ret += ": " + returned(); else ret += std::string(": Unparseable Python traceback"); } return ret; } On Fri, Sep 2, 2011 at 2:15 PM, Dave Abrahams <d...@boostpro.com> wrote: > > on Fri Sep 02 2011, Josh Stratton <strattonbrazil-AT-gmail.com> wrote: > >> Well, right now I'm just passing "this" from inside the scene object, >> so does that need to be wrapped in a shared pointer? > > That's a pretty vague description of what you're doing, so it's hard to > say. I suggest you reduce your question to a minimal case that doesn't > involve any of your domain-specific stuff. Then it will be easy to > answer. > >> >> On Fri, Sep 2, 2011 at 12:19 PM, Dave Abrahams <d...@boostpro.com> wrote: >>> >>> on Thu Sep 01 2011, Jim Bosch <talljimbo-AT-gmail.com> wrote: >>> >>>> boost::python::register_ptr_to_python< boost::shared_ptr<Scene> >(); >>>> >>>> This allows you to return shared_ptr to Python, but because a >>>> boost::shared_ptr can use an arbitrary deleter, Boost.Python can >>>> convert any wrapped Scene object (even one that doesn't hold a >>>> shared_ptr<Scene>) into a shared_ptr<Scene> with correct reference >>>> counting. >>> >>> I might have forgotten by now, but I don't think you need to register >>> shared_ptr, and I don't think the above will have any effect. IIRC I >>> made sure shared_ptr support "just works" out-of-the-box. >>> >>> -- >>> Dave Abrahams >>> BoostPro Computing >>> http://www.boostpro.com> >>> _______________________________________________ >>> Cplusplus-sig mailing list >>> Cplusplus-sig@python.org >>> http://mail.python.org/mailman/listinfo/cplusplus-sig> > > -- > Dave Abrahams > BoostPro Computing > http://www.boostpro.com > > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig@python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig > _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig