Last time we looked at how to use Boost.Python to wrap a very simple piece of C++ code. This time we’re going to take that one step further along, and do the same thing for a more complex C++ example – which includes a C++ Class.
For the purposes of this example – let us assume that we have a “legacy” C++ class (i.e. one that we’re not going to change): which looks something like this:
This (deliberately, slightly contrived) class has three methods (and a constructor). We can set the three 8-bit unsigned integers (uint8_t) directly using the set_data() method; we can print the data to the screen; or we can either import from or export to an unsigned char*.
In order to be able to use the importer & exporter methods with Python (via Boost.Python) we’ll need to further wrap these – as Boost.Python won’t let us use unsigned char* directly.
Whilst this method makes our code on the C++ side slightly more complicated; it significantly simplifies the Python code – and it let’s us use some more powerful features.
To begin let’s start with a simple example.
char const* greet()
return "hello, world";
std::string multi_bob(int n)
std::string name = "Bob";
std::string r = "";
for (int i=0;i<n;i++)
r += name;
using namespace boost::python;
Everything above the BOOST_PYTHON_MODULE line is perfectly ordinary C++ code. The clever bit comes in when we call the BOOST_PYTHON_MODULE macro (which is defined within the Boost.Python header)…
In this case we’re creating a Python module – with two methods: one based on our very simple greet() function (which we’re also going to call greet); and one based on the more complex multi_bob(int) function. Note that for this second function, to show the fact that the linkage between the C++ & Python code can be very flexible, we give it a different name on the Python side. Also note that we don’t need to tell the macro about the signature of the function as this is handled for us by Boost.Python.
I recently found myself needing to call a C++ class from within Python. I didn’t want to call a separate process (as I had previously when using Thrift – see Using Apache Thrift for Python & C++); but rather to call a C++ library directly.
Before I go on I should say that there are a lot of different ways to do this is Python – and I’ve picked one that worked for me. Other techniques are available – and opinion seems quite divided as to which (if any) technique is ‘best’.
To start with we have our C++ class, written in the usual way.
Unfortunately, whilst there are quite a few tutorials on how to use Thrift: some of them concentrate on explaining how Thrift is working behind the scenes (which is important, of course): rather than on how to use it. There also aren’t that many that concentrate on using C++. So having spent some time working through some of the tutorials (and the book Learning Apache Thrift), I though I’d have a go at writing something of a practical guide. I’m quite deliberately not going to focus on how Thrift works: if you want that, let me suggest the Apache Thrift – Quick Tutorial. I’m also going to assume that you have Thrift installed on your computer already (again, there are lots of sets of instruction on how to do this — Google will be your friend), and that you’re using a Linux or MacOS computer. You should be able to follow-along with most of this if you’re using Windows: but there will be a few differences, especially when it comes to compiling C++ files.
If you’re not familiar with the game – the idea is to write the shortest regular expression possible that will select every element of a list, without selecting any elements from a second list. But what are regular expressions, you ask? Well, they’re a special sequence of characters that specify a particular textual patter – so you can use the appropriate regular expression when programming to automatically extract specific text from a list, file, or other text. There are some great tutorials on the web if you want to learn regular expressions (and you really should – because they’re great) – for example regexone.com…
I didn’t want to use lists of Presidents of the United States (as that had been done) – so I decided to have a go at the age-old challenge: animal, mineral, or vegetable…