[C++-sig] copy constructors and multiple instances
Josh Stratton
strattonbrazil at gmail.com
Sat Sep 3 05:27:18 CEST 2011
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 <dave at 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 <dave at 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 at python.org
>>> http://mail.python.org/mailman/listinfo/cplusplus-sig>
>
> --
> Dave Abrahams
> BoostPro Computing
> http://www.boostpro.com
>
> _______________________________________________
> 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