This is a most basic starter with boost-python using homebrew with the following structure
- Assumptions
- Get
boost-python - A simple example:
"Hello World!" - Wrapping multiple functions in a module
- References
All the source code can be found in this repository.
Assumptions
- Familiarity
pythonas a minimum requirement - Have
homebrewinstalled python 2.7- Vague
C/C++knowledge i.e. be able to write a function! Mac OS X- I used El Capitan10.11.6at the time of writing
Get boost-python
You can obtain the correct boost-python through homebrew via the command:
brew install boost --with-python --build-from-source
I think brew install boost should work but it’s a big install and life is short to do it twice
A simple example: "Hello World!"
The following code wraps the C++ function greet() as a python extension
named hello_ext. Save this as a .cpp file. To avoid ambiguity with internal functions
name it something random e.g. hippopotaplusplus.cpp
#include <boost/python.hpp>
char const* greet()
{
return "Greetings!";
}
BOOST_PYTHON_MODULE(hello_ext)
{
using namespace boost::python;
def("greet", greet);
}
- This code cannot be called until it is compiled - see below
greet()is exclusively aC++function-
BOOST_PYTHON_MODULE(hello_ext)defines a module that can be called frompythonasimport hello_ext using namespace boost::pythonallowsdefinstead ofboost::python::defeach time-
The method
boost::python::defdefines the second argument (theC++function)greetas apythonfunction (named by the string)"greet". We call this function inpythonasimport hello_ext hello_ext.greet()if we had used
def("example", greet);we would call inpythonashello_ext.example()
Compiling with Python
The following python module can be used to compile and link the code in
hippopotaplusplus.cpp to a python-friendly module
from distutils.core import setup
from distutils.extension import Extension
ext_instance = Extension(
'hello_ext',
sources=['hippopotaplusplus.cpp'],
libraries=['boost_python-mt'],
)
setup(
name='hello-world',
version='0.1',
ext_modules=[ext_instance])
-
The first
stringargument ofExtensionmust match thevariabledeclared in the.cppfile by the lineBOOST_PYTHON_MODULE(variable)in this case it is
hello_ext. If this is incorrect, the code will compile but an attempt toimportinpythonwill produce the errorImportError: dynamic module does not define init function - The augment
sourcesdefines thecppfile that is to be compiled - The argument of
libraries=['boost_python-mt']is the required library installed byhomebrew - The argument to
ext_modules=[ext_instance])points to the instance ofExtension - The
nameandversionare really for building packages and not necessary here - For more details, the [official docs][5] for
distutilsare well written
Running
The code is compiled with python through the following command
python setup.py build_ext --inplace
which will create the following build/ directory and file
build/
hello_ext.so
This can be directly now called by python with
import hello_ext
hello_ext.greet()
Wrapping multiple functions in a module
We can define several functions in external files by moving greet to its own file greet.cpp and
creating another file with the function meet saved as meet.cpp
char const* meet()
{
return "Nice to meet you from Boost!";
}
We can link this in the following manner with hippopotaplusplus.cpp as
#include <greet.hpp>
#include <meet.hpp>
#include <boost/python.hpp>
BOOST_PYTHON_MODULE(hello_ext)
{
using namespace boost::python;
def("greet", greet);
def("meet", meet);
}
Compiling
The setup.py file to compile the code is structured exactly the same as above
Running
The running of the code is also exactly the same as above except now we can call both functions
import hello_ext
hello_ext.greet()
hello_ext.meet()
References
boost-pythondocshomebrew- example source code
boost::python::defdocsdistutilsdocs