C/C++ function call from Python

Hey there,

in a previous post, i explained how someone could set up things in a C++ class, in order to load a Python module & call a function through that class. Today, i am going to demonstrate the exact opposite! How someone could actually call a C function from a Python script? This is the objective of the current mission!

Setup

The code has been developed on Ubuntu Linux, and the dependencies are the following

  • C / C++ 11
  • Python 2.7

In Windows, instead of building shared library (*.so) files, you will build DLLs.

Preparation

1. Pack all functions in a shared library (*.so)

In our hypothetical scenario, we would like to use  a version of Libc‘s fgetws() where the amount of characters of the buffer to where the input data will be inserted from the keyboard/standard input could vary. Our function should be contained in a shared library that could be loaded from the Python program dynamically, and then call our kgets function that resides inside the library.

1.1 The header file klib.h

extern "C" wchar_t * kgets(int);

1.2 The implementation file klib.cpp

#include <string>
#include "klib.h"

wchar_t * kgets(int size)
{
    wchar_t *b = new wchar_t[size];
    return fgetws(b,size,stdin);
}

Notice that in the declaration of kgets in klib.h, by adding extern “C”, we declare that kgets could be linked from outside, allowing a client C program to call it. By seeing that declaration, the compiler won’t mangle the exported function’s name, allowing the client program to link with it; the function name will be available to the linker.

We compile them through a Makefile:

all:
        g++ -std=c++11 -Wall -fPIC -O2 -c klib.cpp klib.h
        g++ -std=c++11 -shared -o klib.so klib.o
clean:
        rm -f *.so
        rm -f *.o

 

And then we type:

gclkaze@tzertzelos:~/Tzertzelos/Scriptz/PythonC++$ make all
g++ -std=c++11 -Wall -fPIC -O2 -c klib.cpp klib.h
g++ -std=c++11 -shared -o klib.so klib.o
gclkaze@tzertzelos:~/Tzertzelos/Scriptz/PythonC++$ 

 

And our klib.so containing our almighty kgets is ready to be loaded!

2. Load the shared library through Python & call the function

Our Python script uses the ctypes Python module which actually performs the whole thing. It provides library loading & data type conversion utilities, allowing us to first to describe the function that resides inside the shared library, then load it & finally call it. By describing what (exactly) the function call should take as arguments & a return value data type, ctypes ensures to setup things in order to call the function. Of course the given  description/prototype of the function in the Python side, should match one-to-one with the appropriate exported C function that resides in the C side. Otherwise, the function call will fail & our python script will get an exception before calling the exported C function.

Let’s see the client.py script:

 # -*- coding: utf-8 -*-
import ctypes as c
#Load the shared library
klib = c.cdll.LoadLibrary(“./klib.so”)
#Load function
kgets = klib.kgets#Prepare return value & argument
kgets.restype = c.c_wchar_p
kgets.argtypes = [c.c_int]#Get 20 wide string characters from the 
#standard input. Skip new line in the end (‘\n’)
res = kgets(20)[:-1]
print ‘kgets says:’,res

 

(*The call to ctypes.cdll.LoadLibrary is used for shared library files only, not DLLs.)

Execute it:

gclkaze@tzertzelos:~/Tzertzelos/Scriptz/PythonC++$ python client.py 
Tzertzelos Blog!
kgets says: Tzertzelos Blog!

It works!

We were able to:

  • compile fast C functions in a shared library (.so)
  • write a Python script, which by utilizing the power of the ctypes module was able to load our library & call one exported C function

Now go gain some high performance, by extending your C libraries & use Python to wrap them up in shared libraries.

Cheers,

kazeone

 

Linx

Static, Shared Dynamic and Loadable Linux Libraries

Shared Libraries

ctypes — A foreign function library for Python

 

Musix

Oranssi Pazuzu – Värähtelijä

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s