Calling a python function from C++.
I'm using boost 1_31_0 on Mandrake 10.0 Linux. I've created a simple demonstration of calling a python function with C++ object args using python.boost. It currently works with one exception. In the face of a missing python script, it "aborts" instead of properly throwing an exception if I use the "handle<>" machinery that boost.python offers. The following code fragment contains the working code with the stuff that should do the equivalent, but exibits this problem, commented out. PyObject * /* Returns a borrowed reference */ getPythonFunction(string moduleName,string functionName) { // handle<> _module( PyImport_ImportModule(const_cast<char *>(moduleName.c_str()))); // if ( _module.get() == NULL) throwException("The python module \"",moduleName.c_str(),"\" is not available",NULL); // handle<> _namespace(borrowed( PyModule_GetDict(_module.get()))); // if ( _namespace.get() == NULL) throwException("Failed to acquire the dictionary of \"",moduleName.c_str(),"\"",NULL); // handle<> _function(borrowed(PyDict_GetItemString( _namespace.get(),functionName.c_str()))); // if ( _function.get() == NULL) throwException("Failed to find needed function \"",functionName.c_str(),"\"",NULL); // return _function.get(); PyObject *pModule = PyImport_ImportModule(const_cast<char *>(moduleName.c_str())); if ( pModule == NULL) throwException("The python module \"",moduleName.c_str(),"\" is not available",NULL); PyObject *pDict = PyModule_GetDict(pModule); if ( pDict == NULL) throwException("Failed to acquire the dictionary of \"",moduleName.c_str(),"\"",NULL); PyObject *pFunc = PyDict_GetItemString(pDict,functionName.c_str()); if ( pFunc == NULL) throwException("Failed to find requested python function \"",functionName.c_str(),"\"",NULL); Py_DECREF(pModule); return pFunc; } In this form, this function throws a std::run_time exception which is successfully caught with a "catch (exception& x)" clause. With the commented out section active, something is thrown, but it can only be caught with "catch(...)". I'm wondering if anybody can explain this. I'm also wondering if I could contribute this example to boost.python. The python script that I call is: import sys from Greeter import * def AlterGreeting( greeting): greeting.setLanguage("Python") return greeting.greet() if __name__ == '__main__': print 'testing module' greetingObj = Greeter("C++") greeting = AlterGreeting(greetingObj) print greeting Note that the Greeter module is a C++ extension module also created with boost.python using pyste. The C++ part of this example does the same thing that the main module specific section of this python script does. If anybody wants this example, simple request it. I'll provide the complete project, which uses bjam v1, in a tar ball.
In gmane.comp.python.c++, you wrote:
I'm using boost 1_31_0 on Mandrake 10.0 Linux.
I've created a simple demonstration of calling a python function with C++ object args using python.boost. It currently works with one exception. In the face of a missing python script, it "aborts" instead of properly throwing an exception if I use the "handle<>" machinery that boost.python offers. The following code fragment contains the working code with the stuff that should do the equivalent, but exibits this problem, commented out.
Hi Jeff, I'd be interested to see your code. I am trying (not very successfully so far) to figure out this stuff myself, and any working examples are helpful. It sounds like you have a better handle on this stuff (no pun intended) than I do. :-) Please email it to the my email address shown above. Thanks. Faheem.
Jeff Holle <jeff.holle@verizon.net> writes:
I'm using boost 1_31_0 on Mandrake 10.0 Linux.
I've created a simple demonstration of calling a python function with C++ object args using python.boost. It currently works with one exception. In the face of a missing python script, it "aborts" instead of properly throwing an exception if I use the "handle<>" machinery that boost.python offers. The following code fragment contains the working code with the stuff that should do the equivalent, but exibits this problem, commented out.
PyObject * /* Returns a borrowed reference */ getPythonFunction(string moduleName,string functionName) { // handle<> _module( PyImport_ImportModule(const_cast<char *>(moduleName.c_str()))); // if ( _module.get() == NULL) throwException("The python module \"",moduleName.c_str(),"\" is not available",NULL);
// handle<> _namespace(borrowed( PyModule_GetDict(_module.get()))); // if ( _namespace.get() == NULL) throwException("Failed to acquire the dictionary of \"",moduleName.c_str(),"\"",NULL); // handle<> _function(borrowed(PyDict_GetItemString( _namespace.get(),functionName.c_str()))); // if ( _function.get() == NULL) throwException("Failed to find needed function \"",functionName.c_str(),"\"",NULL); // return _function.get();
Why struggle? This should be: object /* Returns a borrowed reference */ getPythonFunction(string moduleName,string functionName) { object _module(handle<>( PyImport_ImportModule( const_cast<char*>(moduleName.c_str())))); return _module.attr(functionName.c_str()); } -- Dave Abrahams Boost Consulting http://www.boost-consulting.com
participants (3)
-
David Abrahams -
Faheem Mitha -
Jeff Holle