How to wrap python object in C/C++?


To wrap existing C or C++ functionality in Python, there are number of options available, which are: Manual wrapping using PyMethodDef and Py_InitModule, SWIG, Pyrex, ctypes, SIP, Boost.Python, and pybind1.

Using the SWIG Module

Let’s take a C function and then tune it to python using SWIG. The SWIG stands for “Simple Wrapper Interface Generator”, and it is capable of wrapping C in a large variety of languages like python, PHP, TCL etc.

Example

Consider simple factorial function fact() in example.c file.

/* File : example.c */
 
 #include <example.h>
// calculate factorial
 int fact(int n) {
     if (n <= 1) return 1;
     else return n*fact(n-1);
 }

Header file

int fact(int n);                                                        

Interface file

Now, in order to add the above c function to python language, you need to write an "interface file" which is the input to SWIG.

/* example.i */
%module example 
%{ /* Put header files here or function declarations like below */
extern int fact(int n); 
%} 

extern int fact(int n); 

Creating the wrapper for python

By simply following the blow, we can wrap the C code into a Python module.

>swig -python example.i

This will create new files with the name of “example_wrap.c” and “example.py”. The “example_wrap.c” file contains a bloated version of our original C code with various error handling code etc. And “example.py” will be imported in our python script.

After this execute the following command:

>gcc -c example.c example_wrap.c \ -I/usr/local/include/python2.7

This will generate position-independent code which will be used in the shared library by compiling “example_wrap.c” and “example.py” files. Note: Replace python2.7 with your Python version. This will generate two object files “example_wrap.o” and “example.o”.

>ld -shared example.o example_wrap.o -o _example.so

Finally, we have to link generated objects files together to create a shared object which is analogous to dll files in windows. Use the above command, this will generate a “_example.so” shared object file. Now we are ready to test out python wrapper by importing it.

>>> import example 
>>> example.fact(5) 
120

Using the Boost Library

Now take a C++ function and then wrap it to python using Boost.Python.

The Boost.Python Library, which is used to wrap python objects in C/C++. The Boost Python library is a framework for interfacing Python and C++. Without using any special tools, it allows us to quickly and seamlessly expose C++ classes functions and objects to Python, and vice-versa.

It is designed to wrap C++ interfaces non-intrusively, so that you should not have to change the C++ code at all in order to wrap it. The library's use of advanced metaprogramming techniques which simplifies its syntax for users, so that wrapping code takes on the look of a kind of declarative interface definition language (IDL).

Example

Let’s take a basic wrapper: we have a function ‘foo’ in a C++ file.

char const* foo()
{
   return "Sample,function";
}

Then write a Boost.python wrapper to expose the “foo” function to Python.

#include <boost/python.hpp>

BOOST_PYTHON_MODULE(sample)
{
    using namespace boost::python;
    def("foo",foo);
}

From the above setup we have built a shared library. The resulting DLL is now visible to Python. Here's a sample Python session –

<<< import sample
<<< print(sample.foo())

Output

Sample, function

By using this basic foo function, we have shared the C++ function to python successfully.

Updated on: 24-Aug-2023

193 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements