Calling C++ Classes from Python, with ctypes…

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.

#include <iostream>

// A simple class with a constuctor and some methods...

class Foo
        void bar();
        int foobar(int);
        int val;

Foo::Foo(int n)
    val = n;

void Foo::bar()
    std::cout << "Value is " << val << std::endl;

int Foo::foobar(int n)
    return val + n;

Next we need to place a C wrapper around the C++ code – since the ctypes system cannot use C++ code… To do this we add the following to the bottom of the file.

// Define C functions for the C++ class - as ctypes can only talk to C...

extern "C"
    Foo* Foo_new(int n) {return new Foo(n);}
    void Foo_bar(Foo* foo) {foo->bar();}
    int Foo_foobar(Foo* foo, int n) {return foo->foobar(n);}

Note that we need to provide a non-class-based name for each Method we want to call.

We now need to build a file from our code.

We could do this by hand:

$ g++ -c -fPIC foo.cpp -o foo.o
$ g++ -shared -W1,-soname, -o foo.o

Or we could use CMake.

The following is the CMakeLists.txtto build foo.cpp.

cmake_minimum_required(VERSION 2.8.9)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")

project (foo)
set (SOURCE foo.cpp)
add_library(foo MODULE ${SOURCE})

Note that I was building on my Mac – hence the MacOS specific line 4. This will work okay on Linux; but it’s not needed.

Now that we’ve written and compiled our C++ – we now need to build a Python wrapper for the Class…

import ctypes

lib = ctypes.cdll.LoadLibrary('./')

class Foo(object):
    def __init__(self, val):
        lib.Foo_new.argtypes = [ctypes.c_int]
        lib.Foo_new.restype = ctypes.c_void_p

        lib.Foo_bar.argtypes = [ctypes.c_void_p]
        lib.Foo_bar.restype = ctypes.c_void_p

        lib.Foo_foobar.argtypes = [ctypes.c_void_p, ctypes.c_int]
        lib.Foo_foobar.restype = ctypes.c_int

        self.obj = lib.Foo_new(val)

    def bar(self):
    def foobar(self, val):
        return lib.Foo_foobar(self.obj, val)

Note the requirement to define the argument types, and the type of the return value (even if there isn’t one – e.g. you’re returning void). Without this you’ll get a segmentation fault (etc.).

Now that we’ve done everything we need to build the module, we can simply import it from within Python.

For example:

from foo import Foo

# We'll create a Foo object with a value of 5...

# Calling will print a message including the value...

# Now we'll use foobar to add a value to that stored in our Foo object, f
print (f.foobar(7))

# Now we'll do the same thing - but this time demonstrate that it's a normal
# Python integer...

x = f.foobar(2)
print (type(x))

The full source code for this simple demo can be found here:

2 thoughts on “Calling C++ Classes from Python, with ctypes…

    1. CMake is a simple way to manage building complex code on Linux / Mac systems. Have a look here ( for a good tutorial.

      Essentially you create the CMakeLists.txt file as described above, then run cmake to create a standard UNIX Makefile. Then you just run make to do the building. In this case the file will be build in the current working directory.

      I hope that helps – and sorry for the delay in replying.

Leave a Reply

Your email address will not be published. Required fields are marked *