using extract with embedded boost::python
Hi, I am getting an error when I run example code like this: // Retrieve the main module. /* object main = import("__main__"); // Retrieve the main module's namespace object global(main.attr("__dict__")); // Define greet function in Python. object result = exec( "def greet(self): \n" " return 'Hello from Python!' \n", global, global); // Create a reference to it. object greet = global["greet"]; // Call it. std::string message = extract<std::string>(greet()); It gives error_already_set, which I catch, but then it crashes on shutdown during garbage collection. The extract line is causing the crash. Strangely this works: object main_module(( handle<>(borrowed(PyImport_AddModule("__main__"))))); object main_namespace = main_module.attr("__dict__"); handle<> ignored((PyRun_String( "import myPython" ))); int five_squared = extract<int>(main_namespace["result"]); g_log->Log( "%d\n", five_squared ); Can anyone demystify the difference to a boost:python newbie? Thanks Simon http://www.simonpickles.com --- http://www.squirtualreality.com _________________________________________________________________ Could you be the guest MSN Movies presenter? Click Here to Audition http://www.lightscameraaudition.co.uk
Sorry, A cut-n-paste error, the code which works is the boost example: object main_module(( handle<>(borrowed(PyImport_AddModule("__main__"))))); object main_namespace = main_module.attr("__dict__"); handle<> ignored((PyRun_String( "result = 5 ** 2" , Py_file_input , main_namespace.ptr() , main_namespace.ptr()) )); int five_squared = extract<int>(main_namespace["result"]); ---------------------------------------------------------------- http://www.simonpickles.com --- http://www.squirtualreality.com
From: "Simon Pickles" <sipickles@hotmail.com> Reply-To: Development of Python/C++ integration <c++-sig@python.org> To: c++-sig@python.org Subject: [C++-sig] using extract with embedded boost::python Date: Sun, 03 Jun 2007 19:35:23 +0100
Hi,
I am getting an error when I run example code like this:
// Retrieve the main module. /* object main = import("__main__");
// Retrieve the main module's namespace object global(main.attr("__dict__"));
// Define greet function in Python. object result = exec( "def greet(self): \n" " return 'Hello from Python!' \n", global, global);
// Create a reference to it. object greet = global["greet"];
// Call it. std::string message = extract<std::string>(greet());
It gives error_already_set, which I catch, but then it crashes on shutdown during garbage collection. The extract line is causing the crash.
Strangely this works:
object main_module(( handle<>(borrowed(PyImport_AddModule("__main__")))));
object main_namespace = main_module.attr("__dict__");
handle<> ignored((PyRun_String( "import myPython" )));
int five_squared = extract<int>(main_namespace["result"]);
g_log->Log( "%d\n", five_squared );
Can anyone demystify the difference to a boost:python newbie?
Thanks
Simon
http://www.simonpickles.com --- http://www.squirtualreality.com
_________________________________________________________________ Could you be the guest MSN Movies presenter? Click Here to Audition http://www.lightscameraaudition.co.uk
_______________________________________________ C++-sig mailing list C++-sig@python.org http://mail.python.org/mailman/listinfo/c++-sig
_________________________________________________________________ Txt a lot? Get Messenger FREE on your mobile. https://livemessenger.mobile.uk.msn.com/
Simon Pickles wrote:
Sorry, A cut-n-paste error, the code which works is the boost example:
object main_module(( handle<>(borrowed(PyImport_AddModule("__main__")))));
object main_namespace = main_module.attr("__dict__");
handle<> ignored((PyRun_String(
"result = 5 ** 2"
, Py_file_input , main_namespace.ptr() , main_namespace.ptr()) ));
int five_squared = extract<int>(main_namespace["result"]);
Please have a look at the tests that are part of the boost source distribution. Notably, libs/python/tests/exec.cpp contains functionality similar to the above, and is shown to work correctly on all tested platforms. Also, it would be good to figure out what (python) exception is raised (indicated by the exception_already_set in C++). You can query this using PyErr_Fetch(). (I'm hoping I will get around to wrap that and related functions in boost.python in time for boost 1.35.) Regards, Stefan -- ...ich hab' noch einen Koffer in Berlin...
Thanks Stefan. On consulting libs/python/tests/exec.cpp I got the extract to work, with simple data types, like int and std::string. How can I do the same for a function. I tried: // C++ python::dict global; python::object result = python::exec_file("myPython.py", global, global)l python::object greet = global["greet"]; std::string message = python::extract<std::string>(greet()); // MYPYTHON.PY def greet(self): return "hello, world!" This gives an error. Its the example from the documentation. Then, can I also pass parameters? As for PyErr_Fetch, since I am not using a console application (win32), I don't know what to do with PyErr_Fetch or PyErr_Print! Sorry, not big on console apps! Keep up the good work! I'm loving what I see! Regards Simon Stefan Seefeld wrote:
Simon Pickles wrote:
Sorry, A cut-n-paste error, the code which works is the boost example:
object main_module(( handle<>(borrowed(PyImport_AddModule("__main__")))));
object main_namespace = main_module.attr("__dict__");
handle<> ignored((PyRun_String(
"result = 5 ** 2"
, Py_file_input , main_namespace.ptr() , main_namespace.ptr()) ));
int five_squared = extract<int>(main_namespace["result"]);
Please have a look at the tests that are part of the boost source distribution. Notably, libs/python/tests/exec.cpp contains functionality similar to the above, and is shown to work correctly on all tested platforms.
Also, it would be good to figure out what (python) exception is raised (indicated by the exception_already_set in C++). You can query this using PyErr_Fetch(). (I'm hoping I will get around to wrap that and related functions in boost.python in time for boost 1.35.)
Regards, Stefan
-- http://www.simonpickles.com --- http://www.squirtualreality.com
Simon Pickles wrote:
Thanks Stefan.
On consulting libs/python/tests/exec.cpp I got the extract to work, with simple data types, like int and std::string.
How can I do the same for a function. I tried:
// C++ python::dict global; python::object result = python::exec_file("myPython.py", global, global)l
python::object greet = global["greet"]; std::string message = python::extract<std::string>(greet());
// MYPYTHON.PY def greet(self): return "hello, world!"
This gives an error. Its the example from the documentation.
What error ? I'm not exactly sure about the above: greet() returns a new object, and extract<std::string> returns something (a proxy ?) which is implicitly convertible to a std::string. Is it possible that the lifetime of the object to be extracted from is slightly shorter than that of the proxy ? David ? Does it make a difference if you store the result of greet() in a local object and extract from that ?
Then, can I also pass parameters?
pass to what ? The function call ? That's all covered in the tutorial / manual.
As for PyErr_Fetch, since I am not using a console application (win32), I don't know what to do with PyErr_Fetch or PyErr_Print! Sorry, not big on console apps!
I don't quite understand the relation to "console app". If your platform doesn't have support for stdout / stderr, you surely have other means to display text. Regards, Stefan -- ...ich hab' noch einen Koffer in Berlin...
participants (2)
-
Simon Pickles -
Stefan Seefeld