You are on page 1of 4

Table of Contents

How to integrate C++ code in Python



Introduction
Layout
Wrapping

How to install Boost.Python ?
File organisation
Compilation
Install the wrapped packages
Memory management
How to integrate C++ code in Python
Introduction
Existing libraries can be interfaced with the Python language without rewriting all the code. There are
different tools to achieve this task for different langage. However, in this document, we will only deals with
C++ code wrapping via the Boost.Python library.
Layout
In order to have homogeneous packages, we advice to respect a particular package layout.
src/
cpp/ : contains cpp library source files
include/ : contains cpp library header
wrapper/ : contains wrapper code
my_package/ : contains python module
For more information, read the How to create an open alea package document.
Wrapping
We recommend to use Boost.Python to create C++ to Python wrappers.
Boost.Python wrappers are C++ code to expose C++ classes and functions in python.
Please read the Boost.Python tutorial to learn how to write Boost.Python wrappers.
1/4
How to install Boost.Python ?
On Linux
Use the standard installation procedure of your distribution (apt-get, urpmi, yum?). Most linux distributions
include a boost binary package.
On Windows
You can download the sources on the boost web site and compile them.
However, an installer for MinGw, Visual Studio 7.1 and 8. is distributed on the OpenAlea website :
Boost.Python for windows.
File organisation
Boost.Python uses extensively C++ template. They can lead to compilation problems. Moreover, templates
use a huge amount of memory. To avoid this kind of problems, we advice to separate wrapper code in
different files.
A wrapped Python module is usually declared with the macro BOOST_PYTHON_MODULE. ex:
// Define python module sceneobject
// Note : Python module and generated dll/so file must have the SAME NAME
BOOST_PYTHON_MODULE(sceneobject)
{
//scene_object class wrapper
class_<scene_objectWrap, boost::noncopyable>("sceneobject", "Abstract base
class for scene object" )
.def("display", &scene_object::display, "Display the object name")
.def("get_name", pure_virtual(&scene_object::get_name), "Return the object
name");

//leaf class wrapper
class_<leaf, bases<scene_object> >("leaf", "Leaf object" );
}
Instead of declaring all the class inside the same block, we declare each class wrappers class_< > in a
separate function placed in an external file. This allow to have separate compilation process for each file. The
previous example is divided as follow : sceneobject_wrap.cpp, class_scene_object.h,
class_scene_object.cpp, class_leaf.h and class_leaf.cpp:
// sceneobject_wrap.cpp

#include "class_scene_object.h"
#include "class_leaf.h"

// Define python module sceneobject
BOOST_PYTHON_MODULE(sceneobject)
{
2/4
class_scene_object();
class_leaf();
}

// class_scene_object.h
#ifndef __CLASS_SCENE_OBJECT__
#define __CLASS_SCENE_OBJECT__

void class_scene_object();

#endif

// class_scene_object.cpp

void class_scene_object()
{
class_<scene_objectWrap, boost::noncopyable>("sceneobject", "Abstract base
class for scene object" )
.def("display", &scene_object::display, "Display the object name")
.def("get_name", pure_virtual(&scene_object::get_name), "Return the object
name");
}

// class_leaf.h
#ifndef __CLASS_LEAF__
#define __CLASS_LEAF__

void class_leaf();

#endif

// class_leaf.cpp

void class_leaf()
{
class_<leaf, bases<scene_object> >("leaf", "Leaf object" );
}

Compilation
Boost.Python tutorial recommend to use BJam tool for the compilation.
Instead, we recommend to use scons, for a better integration in Python. Scons is a portable tool to
compile modules on Linux and Windows plateforms, and manage dependencies between files and libraries.
We developed the tool SConsX which extends scons base functionnalities in order to facilitate build process
with specific tools like Boost.Python.
#The SConsX code to create a scons environment which support Boost.Python
compilation
from openalea.sconsx import config, environ
3/4

ALEAConfig= config.ALEAConfig
ALEAEnvironment= config.ALEAEnvironment


options = Options( 'options.py', ARGUMENTS )

wrapper_conf = ALEAConfig(name,['boost_python', 'alea'])

wrapper_env = ALEAEnvironment( wrapper_conf, 'options.py', ARGUMENTS )

Install the wrapped packages
Once C++ code has been wrapped to Python, wrapped package must be considered as a Python package
which link with dynamic C++ libraries. The installation procedure is then supported by the Python distutils
module.
We have also developed a extension Deploy in order to install external libraries on the system within Python
framework.
Memory management
Interfacing C++ code with Python can be a little confusing concerning the memory management, and
particulary the dynamic object lifetime. Indeed, object ownership can be difficult to implement correctly
because an object can be created either by C++ code or by Python code.
To tackle this problem, we recommend to use smart pointers.
Boost Smart pointer definition :
Smart pointers are objects which store pointers to dynamically allocated (heap) objects. They behave much
like built-in C++ pointers except that they automatically delete the object pointed to at the appropriate time.
Smart pointers are particularly useful in the face of exceptions as they ensure proper destruction of
dynamically allocated objects. They can also be used to keep track of dynamically allocated objects shared
by multiple owners.
You can find an implementation and the usage of smart pointers (formely RefCountObject and
RefCountPtr in the starter package.
4/4