Use C++ code in Python

Use C++ code in Python

Python is famous for its simplicity and readability. However, it’s not the fastest language. If you have a performance-critical application, you may want to use C++ code in Python. This post explains how to use C++ code in Python.

If I have Foo class in C++:

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>

class Foo
{
public:
~Foo() { std::cout << "Foo::~Foo()" << std::endl; }
void bar()
{
std::cout << "Hello, World!" << std::endl;
}
};

To use it in Python, I need to expose it to C API using extern "C":

1
2
3
4
5
6
7
8
9
10
11
12
13
extern "C"
{
Foo* Foo_new() { return new Foo(); }
void Foo_bar(Foo* foo) { foo->bar(); }
void Foo_delete(Foo* foo)
{
if(foo != NULL)
{
delete foo;
foo = NULL;
}
}
}

Then, I need to compile it to a shared library:

1
g++ -shared -fPIC -o libfoo.so foo.cpp

Now, I can use it in Python:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from ctypes import cdll
import ctypes

lib = cdll.LoadLibrary('./libfoo.so')

class Foo:
def __init__(self):
lib.Foo_new.restype = ctypes.c_void_p
lib.Foo_bar.argtypes = [ctypes.c_void_p]
lib.Foo_delete.argtypes = [ctypes.c_void_p]

self.obj = lib.Foo_new()

def __del__(self):
if self.obj:
lib.Foo_delete(self.obj)
self.obj = None

def bar(self):
lib.Foo_bar(self.obj)


f = Foo()
f.bar()

Note:

  1. As I used new in C++, I need to delete it in Python to avoid memory leak. That’s why I defined __del__ method.
  2. It’s necessary to define restype and argtypes for each c++ function. Otherwise, Python program may have error or crash.
    e.g., If I don’t have restype defined for Foo_new and argtypes for Foo_delete, the default return type will be int. When deleting Foo object, int will be passed into Foo_delete function. Then we can have error: OSError: exception: access violation reading 0x00000000B7727FAF This error indicates that I’m trying to delete a block of memory that I don’t have permission to access.

Comments