|
| 1 | +/** |
| 2 | + * \file |
| 3 | + * \brief Simple example on how to call a Python function from C++ code. |
| 4 | + * |
| 5 | + * Useful resources: |
| 6 | + * - Actually the boost python documentation starts to get a bit better: |
| 7 | + * http://www.boost.org/doc/libs/1_61_0/libs/python/doc/html/tutorial/tutorial/embedding.html |
| 8 | + * - A bit outdated but contains a function to extract traceback from |
| 9 | + * exceptions: https://wiki.python.org/moin/boost.python/EmbeddingPython |
| 10 | + */ |
| 11 | +#include <iostream> |
| 12 | +#include <string> |
| 13 | +#include <boost/python.hpp> |
| 14 | + |
| 15 | +using namespace boost::python; |
| 16 | + |
| 17 | +int main( int argc, char ** argv ) { |
| 18 | + // It is important to initialize the Python interpreter before running any |
| 19 | + // Python code. |
| 20 | + Py_Initialize(); |
| 21 | + |
| 22 | + try |
| 23 | + { |
| 24 | + // based on the example from |
| 25 | + // http://www.boost.org/doc/libs/1_46_0/libs/python/doc/v2/exec.html |
| 26 | + |
| 27 | + // Retrieve the main module. |
| 28 | + object main = import("__main__"); |
| 29 | + |
| 30 | + // Retrieve the main module's namespace |
| 31 | + object global(main.attr("__dict__")); |
| 32 | + |
| 33 | + // Import my module |
| 34 | + object mypylib = import("boost_python_catkin_example.mypylib"); |
| 35 | + |
| 36 | + // Create a reference to the hello function in the module. |
| 37 | + object hello = mypylib.attr("hello"); |
| 38 | + object SomeClass = mypylib.attr("SomeClass"); |
| 39 | + |
| 40 | + // Call it. |
| 41 | + std::string message = extract<std::string>(hello()); |
| 42 | + std::cout << message << std::endl; |
| 43 | + |
| 44 | + object some_class_obj = SomeClass(); |
| 45 | + some_class_obj.attr("set_value")(42); |
| 46 | + int value = extract<int>(some_class_obj.attr("get_value")()); |
| 47 | + std::cout << "Value: " << value << std::endl; |
| 48 | + } |
| 49 | + catch (const error_already_set &) |
| 50 | + { |
| 51 | + // When the Python code raises an error, this will result in a |
| 52 | + // boost::python::error_already_set exception in C++. Unfortunately |
| 53 | + // this exception does not contain any information about the nature of |
| 54 | + // the error, so we need to interface with the Python C API to get more |
| 55 | + // information. |
| 56 | + PyErr_Print(); |
| 57 | + |
| 58 | + // To handle based on exception type: |
| 59 | + //if (PyErr_ExceptionMatches(PyExc_ZeroDivisionError)) |
| 60 | + //{ |
| 61 | + // // handle ZeroDivisionError specially |
| 62 | + //} |
| 63 | + |
| 64 | + return 1; |
| 65 | + } |
| 66 | + return 0; |
| 67 | +} |
0 commit comments