This short tutorial will show you how to get started creating a python wrapper using the boost python library to construct and call C++ functions from python. These are actually quite easy to create basic support for and can typically be created in a matter of minutes to give python support to your shared lib's. A typical use case where I have been using them is to wrap a C++ client lib in a C++ client / server application so that it can be used to display web pages in django.

Before you get started on the code you are going to need to get the boost python wrappers. In debian / ubuntu this should be easy just install the package 'libboost-python-dev' using apt-get.

Before we can produce a python wrapper we need something in C++ that we can call. So for this I am going to use the following basic example of a C++ class

class MyClass {
    public:
        MyClass() { }
        ~MyClass() { }

        std::string Example() {
            return "Hello World";
        }
};

To create a basic python wrapper we will need the following C++ headers from the boost python wrappers.

#include <boost/python.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/init.hpp>
#include <boost/python/operators.hpp>
#include <boost/python/call_method.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/implicit.hpp>
#include <boost/python/return_by_value.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/overloads.hpp>
#include <boost/ref.hpp>
#include <boost/utility.hpp>

This will give us access to the correct macro's which will automatically generate the correct wrappers for us. We can declare our python module as 'MyClass_py' this of course means when we are compiling we will be creating a shared object 'MyClass_py.so' so that python can load it with 'import MyClass_py.so'

BOOST_PYTHON_MODULE(MyClass_py)
{

}

Anything that we wish to wrap will be added inside the BOOST_PYTHON_MODULE above and wrapping classes is easy and example of being able to map the C++ to python is below that can be extended to take care of all the functions that you wish to support. You should also be aware that there is limited / no support in dealing with operator overloading in python wrappers however there are ways to deal with this issue and I will mention them in another tutorial.

BOOST_PYTHON_MODULE(MyClass_py)
{
    class_<MyClass>( "MyClass", init<>() )

        .def("Example", &MyClass::Example)    
    ;    
}

There is of course a matter of getting the code to compile which involves making a shared lib. The name of the shared lib is important it must match the name in the BOOST_PYTHON_MODULE or the module will not load into python.

g++ -shared -Wall MyClass_py.cpp -o MyClass_py.so -I/usr/include/python2.6/ -lboost_python -lpython2.6

There there is a matter of testing the above with python. Here is a simple example.

>>> import MyClass_py
>>> obj = MyClass_py.MyClass()
>>> obj.Example()
'Hello World'

Here is a full working example below that can be copied / pasted into a file.

#include <string>
#include <boost/python.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/init.hpp>
#include <boost/python/operators.hpp>
#include <boost/python/call_method.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/implicit.hpp>
#include <boost/python/return_by_value.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/overloads.hpp>
#include <boost/ref.hpp>
#include <boost/utility.hpp>

using namespace boost::python;

class MyClass {
    public:
        MyClass() { }
        ~MyClass() { }

        std::string Example() {
            return "Hello World";
        }
};


BOOST_PYTHON_MODULE(MyClass_py)
{

    class_<MyClass>( "MyClass", init<>() )

        .def("Example", &MyClass::Example)

    ;

}


Did You find this page useful?

Yes No



Last Modified: 17 December 2016

Releated Posts


2017-04-25 - Linux Programming - Signals the easy way
2017-03-01 - Shooting yourself in the head with threads
2013-08-22 - CPP - Prevent an object by being copied with boost::noncopyable
2013-04-09 - Python - How to find out if a key exists in a dictionary
2013-03-29 - CPP - Why you need a copy constructor
2013-03-27 - CPP -boost::optional
2012-11-06 - C++ - Stringstream example
2012-08-14 - Python - while else statement
2012-08-09 - C++ - Check an IP Address is in a IP Mask
2012-06-30 - CPP - Creating A basic python wrapper
2012-06-16 - CPP - Using gperf
2012-05-10 - CPP - Optional function arguments
2012-03-19 - CPP - Read / Write std::map to a file.
2012-02-22 - Python - 2d Arrays don't work.