Skip to content

Commit f6dc835

Browse files
committed
Add example on how to call Python function in C++.
1 parent 22e43ef commit f6dc835

File tree

4 files changed

+97
-1
lines changed

4 files changed

+97
-1
lines changed

CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,17 @@ target_link_libraries(mycpplib
4040
)
4141

4242

43+
add_executable(use_pylib
44+
src/use_pylib.cpp
45+
)
46+
47+
target_link_libraries(use_pylib
48+
${catkin_LIBRARIES}
49+
${Boost_LIBRARIES}
50+
${PYTHON_LIBRARIES}
51+
)
52+
53+
4354
#############
4455
## Install ##
4556
#############

package.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0"?>
22
<package>
33
<name>boost_python_catkin_example</name>
4-
<version>1.0.0</version>
4+
<version>1.1.0</version>
55
<description>
66
A minimal example package on how to use Boost::Python with catkin.
77
</description>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"""Some simple example module that is going to be used in C++."""
2+
3+
4+
def hello():
5+
"""Return a hello message."""
6+
return "Hello C++. I'm Python, looking forward to work with you!"
7+
8+
9+
class SomeClass:
10+
11+
def __init__(self):
12+
self.value = None
13+
14+
def set_value(self, value):
15+
self.value = value
16+
17+
def get_value(self):
18+
return self.value

src/use_pylib.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
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

Comments
 (0)